如何改进sql server查询优化器的结果

时间:2010-01-11 14:45:17

标签: sql-server performance

问题很简单:我该怎么做才能确保SQL Server查询优化器具有选择“最佳”查询计划所需的所有信息?

这个问题的背景是,最近我们遇到越来越多的SQL Server选择错误查询计划的情况,即添加查询提示,加入提示或明确使用临时表而不是“一个大”的情况SQL“大幅提升了性能。我真的很惊讶查询优化器提供了很多不好的结果,所以我想知道我们是否做错了。没有索引丢失(根据查询分析器和常识),并且维护任务经常更新统计信息。

让我强调一下,我不是在谈论丢失索引!我在谈论存在“好”和“坏”查询计划的情况(考虑到数据库的当前状态),并且SQL Server选择“坏”计划,尽管存在的索引允许它使用“好计划。我想知道是否有可能改进查询优化器的结果,而不必手动优化所有查询(使用查询提示或USE PLAN)。

3 个答案:

答案 0 :(得分:2)

生成查询计划的方式多于索引和统计信息。

有关这些内容的详细解释,请参阅13 things you should know about statistics and the query optimizer

答案 1 :(得分:1)

SQL Server的查询优化器基于统计数据。如果统计信息不是最新的,或者索引被许多插入或删除“倾斜”,那么优化器有时会出错。

大部分时间它做得很好。你应该检查的事情:

  • 您的统计信息是最新的吗?

  • 你的索引是否支离破碎?您是否有定期的索引维护工作?

  • 您是否违反参数嗅探,导致不适当的计划被缓存?

  • 您的数据是否足够有选择性地选择索引?

我不会使用查询HINTS,除非你真的必须作为最后的手段。他们有一种习惯性的回忆困扰你。

答案 2 :(得分:1)

很多时候,我发现可以通过将查询分成两个或多个查询来优化过大的查询,并将临时结果存储在临时表中。我知道查询变得太大时没有严格的规则; 20个表的简单“顺序”内连接可以正确优化,8个表上奇怪的奥术连接可能会变得很糟糕。当发生这种情况时,通常我会尝试尽可能多地“拉出”第一个查询来处理“小”表并将尽可能小的数据集返回到临时表中,然后在第二个查询来处理“大”表。 (“小”和“大”当然完全相对于你的情况。)

我提出解释这个问题的经验法则是,对于任何“通用”的“一刀切”算法,某些查询可能会变得太大或太复杂,无法生成最佳查询计划在合理的时间内。简而言之,虽然总的来说你可以把查询写成一个大块,但将它们分成可管理的块通常更有意义。 (我知道我过去读过有关这个主题的文章,但这个主题并不经常出现,我不记得我何时何地阅读它们。)