我有两个完全相同的SQL数据库,每个表中包含几乎相同的记录。它们之间的唯一区别是,一个位于我的本地计算机上,另一个位于Azure中。但是,在调查了性能问题后,我发现两个数据库针对某些查询产生了不同的执行计划。举一个例子,这是一个简单的查询,运行大约需要1秒钟。
select count(*) from Deposits
inner join households on households.id = deposits.HouseholdId
where CashierId = 'd89c8029-4808-4cea-b505-efd8279dc66d'
很明显,内部联接需要省略,因为它对最终结果没有帮助。实际上,在我的本地计算机上已将其省略,但这对于Azure而言并非如此。这是两张图片,分别显示了我的本地计算机和Azure的执行计划。
仅向您提供有关发生的情况的背景,一切运行良好,直到我将Azure数据库缩减为Basic 5 DTU。之后,一些查询变得非常缓慢,我不知道为什么。我再次放大了Db实例,但没有任何改善。然后,我重新构建了索引,并注意到,如果按正确的顺序重新构建它们,查询将再次按预期开始执行。但是,我绝对不知道为什么我需要按某些特定顺序重建它们,甚至更不用说如何确定正确的顺序。现在,几乎所有与Deposits
表相关的查询都存在问题。我尝试重建索引,但没有任何改善。我怀疑这与PK指数有关,但我不太确定。该表包含约30万行。
答案 0 :(得分:1)
您的数据库可能具有相同的架构和大约的记录数,但是很难使它们相同。您确定您的数据库相同吗?
SELECT SERVERPROPERTY(N'ProductVersion');
他们运行的硬件怎么样?中央处理器?记忆?磁盘?我是说它是Azure,对吗?很难知道您正在使用什么实际服务器硬件。 SQL Server的查询优化器将针对硬件差异进行调整。此外,即使硬件和软件完全相同... 使用数据库的事实也可以使它们的统计数据有所不同。首次运行查询时,将使用统计信息对查询进行评估和优化。该查询的所有后续调用将使用该初始缓存的查询计划。桌子随着时间而变化,它们变得更高。数据的形状发生变化,这意味着旧的缓存查询计划最终可能会失宠。某些事情可以重塑数据并更改统计信息,从而使查询计划缓存无效,例如重建索引。尝试这个。要对每个语句强制执行新的查询计划,请添加
OPTION (RECOMPILE)
声明到查询的底部。这有助于或稳定性能吗?此外-这是一个艰苦的尝试-但我可以假设您不是一遍又一遍地使用完全相同的查询吗?更有意义的是您尚未对GUID进行硬编码,而我们确实已经为以@CashierID
作为参数的对象创建了查询计划?如果是这样,那么您现有的查询计划可能成为参数嗅探的受害者,您要提取的查询计划针对某些特定的GUID进行了优化,并且在传递其他任何内容时效果不佳。
有关该语句的详细信息,请查看here。要进一步了解为什么很难拥有相同的数据库,请查看here和here。
祝你好运!希望您可以对它进行排序。