同一查询的不同执行计划
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了同一查询的不同执行计划相关的知识,希望对你有一定的参考价值。
我有两个相同的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指数有关,但我不太确定。该表包含大约300k行。
您的数据库可能具有相同的模式和大致的记录数,但很难使它们相同。你确定你的数据库是相同的吗?
SELECT SERVERPROPERTY(N'ProductVersion');
他们运行的硬件怎么样?中央处理器?记忆?磁盘?我的意思是它是Azure,对吗?很难知道您正在使用的实际服务器硬件。 SQL Server的查询优化器将根据硬件差异进行调整。此外,即使硬件和软件完全相同......只是数据库的使用方式不同,这使得它们在统计数据上存在差异。第一次运行查询时,将使用统计信息对其进行评估和优化。该查询的所有后续调用都将使用最初缓存的查询计划。表随着时间的推移而变化,它们变得更高。数据的形状发生了变化,这意味着旧的缓存查询计划最终会失宠。某些事情可以重塑数据并对统计信息进行更改,从而使查询计划缓存无效,例如重建索引。试试这个。要在每个语句上强制执行新的查询计划,请添加
OPTION (RECOMPILE)
声明底部的语句。这有助于或稳定表现吗?此外 - 这是一个拉伸 - 但我可以假设你不是一遍又一遍地使用那个完全相同的查询吗?更有意义的是你没有硬编码那个GUID,而且我们确实为@CashierID
作为参数的东西创建了一个查询计划?如果是这样,那么您现有的查询计划可能会成为参数嗅探的牺牲品,其中您提取的查询计划针对某些特定GUID进行了优化,并且在您传入其他任何内容时效果不佳。
有关该语句的更多信息,请查看here。为了更好地了解为什么难以拥有相同的数据库,请查看here和here。
祝好运!希望你能把它分类。
以上是关于同一查询的不同执行计划的主要内容,如果未能解决你的问题,请参考以下文章