提高sql server查询优化器结果的方法

Posted

技术标签:

【中文标题】提高sql server查询优化器结果的方法【英文标题】:Ways to improve sql server query optimizer results 【发布时间】:2010-01-11 14:45:17 【问题描述】:

问题很简单:我可以做些什么来确保 SQL Server 查询优化器拥有选择“最佳”查询计划所需的所有信息?

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

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

【问题讨论】:

【参考方案1】:

查询计划的生成方式不仅仅是索引和统计信息。

请参阅13 things you should know about statistics and the query optimizer 以获得对这些的详细说明。

【讨论】:

【参考方案2】:

很多时候,我发现一个过大的查询可以通过将其分成两个或多个查询来进行优化,并将中间结果存储在临时表中。我不知道查询何时变得太大的硬性规则。可以适当优化 20 个表的简单“顺序”内部连接,8 个表上的奇怪的奥术连接可能会被搞砸。发生这种情况时,通常我会尽可能多地“拉出”到第一个查询中,以处理“小”表并将尽可能小的数据集返回到临时表中,然后在第二个查询来处理“大”表。 (当然,“小”和“大”完全取决于你的情况。)

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

【讨论】:

可能是因为 SQL Server 每批只存储一个查询计划。 @Mitch:那么,有没有一种有用的替代方法来拆分查询?我观察到类似的行为......【参考方案3】:

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

大多数时候它都做得很好。您应该检查的事项:

您的统计数据是最新的吗?

您的索引是否碎片化?您有定期的定期索引维护工作吗?

您是否因参数嗅探而犯规,导致缓存不适当的计划?

您的数据的选择性是否足以选择索引?

除非万不得已,否则我不会使用查询提示。他们有一个讨厌的习惯,会回来困扰你。

【讨论】:

嗯,是的,我的问题的重点是我想避免提示,而是帮助查询优化器正确地工作;所以我完全同意你的看法。 :-) 索引和统计数据经常被更新/重组,所以这不应该是问题。关于数据:嗯,这取决于用户输入的内容;这不是我能控制的……

以上是关于提高sql server查询优化器结果的方法的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server的优化器会缓存标量子查询结果集吗

sql server 统计信息

如何提高查询性能?

Sql Server中执行计划的缓存机制

Oracle查询速度优化问题

sql Server 查询方法的优化