Mik*_*ike 6 sql-server performance entity-framework parameter-sniffing multi-tenant
我在SQL Server 2012中有一个多租户数据库,其中每个租户的行由一tenant_id列(即共享数据库,共享模式方法)标识.一些租户,特别是较新的租户,行数很少,而其他租户则很多.
SQL Server的查询优化器通常根据第一次执行时提供的参数构建查询计划,然后即使提供了不同的参数,也可以将此计划重新用于所有将来的查询.这称为参数嗅探.
我们在数据库中遇到的问题是SQL Server有时会根据指向较小租户的参数构建这些计划,这对于该租户很有效,但是当它将缓存计划重新应用于更大的租户时,它会发生灾难性的失败(通常是时间安排)事实上).通常情况下,只有当我们的一个大租户与我们联系遇到超时错误时才会发现这种情况,然后我们必须进入系统并手动清除所有查询计划以纠正它.
您可以使用查询提示来阻止SQL Server缓存查询计划(OPTIMIZE FOR UNKNOWN),但这会导致一些额外的开销,因为每次调用查询时都会重新生成查询计划.另一个问题是我们使用的Entity Framework无法指定OPTIMIZE FOR UNKNOWN查询提示.
所以问题是 - 关于参数嗅探的多租户数据库的最佳实践是什么?有没有办法在数据库范围内禁用参数嗅探而无需在每个查询中指定它?如果是这样,这是最好的方法吗?我应该以其他方式对数据进行分区吗?还有其他一些我没想到的方法吗?
我也遇到过类似的问题,并通过像这样传递参数成功解决了它:
CREATE PROCEDURE [dbo].[InsertAPCheck]
@APBatchID int = Null,
@BankAccountID int = Null
AS
/* copy parameters to temporary variables */
SELECT @xAPBatchId = APBatchId, @xBankAccountID = @BankAccountID
.
.
/* now run the meat of your logic using the temp variables */
SELECT * FROM myTable where Id=@xAPBatchId.....etc.
Run Code Online (Sandbox Code Playgroud)
换句话说,为传入的每个参数在 1-1 的基础上创建一个局部变量,然后仅在 SP 逻辑中引用这些新变量。我可能错过了 SQL Server 可以为我做的一些优化,但最重要的是,我错过了参数嗅探启动时真正可怕的性能。
在你的情况下,也许你可以尝试只对多租户 ID 执行此操作(我假设它是所有 SP 的参数?),并让 SQL Server 优化其余参数(如果可以的话)。
| 归档时间: |
|
| 查看次数: |
8482 次 |
| 最近记录: |