您如何确保新索引不会减慢查询速度?

时间:2011-09-16 20:58:35

标签: sql-server sql-server-2008 query-optimization sql-server-2008-r2

当我们添加或删除新索引以加快某些速度时,我们最终可能会放慢速度。 为了防止这种情况,在创建新索引后,我正在执行以下步骤:

  1. 启动Profiler,
  2. 运行一个SQL脚本,其中包含许多我不想放慢的查询
  3. 将跟踪从文件加载到表中,
  4. 在添加(或删除)索引之前,根据先前运行的结果分析CPU,读取和写入跟踪。
  5. 这是一种自动化的方式,可以满足我的需求。但是,我不确定是否有更好的方法。是否有一些工具可以满足我的需求?

    编辑1 投票结束我的问题的人,您能解释一下原因吗?

    编辑2 我搜索了一下,但没有找到任何解释添加索引如何减慢选择的内容。然而,这是一个众所周知的事实,所以应该有某种东西。如果什么都没有出现,我可以稍后写几个例子。

    编辑3 这样的一个例子是:两列高度相关,如身高和体重。我们有一个高度索引,对我们的查询没有足够的选择性。我们在权重上添加一个索引,并运行一个包含两个条件的查询:高度范围和权重范围。因为优化器不知道相关性,所以它严重低估了我们查询的基数。

    另一个例子是在增加列上添加索引(例如OrderDate)会严重减慢查询的速度,例如OrderDate> SomeDateAfterCreatingTheIndex。

4 个答案:

答案 0 :(得分:8)

最终您要求的内容可以改为'如何确保已经使用最佳,快速计划的查询不会被“优化”为更糟糕的执行计划?'

由于参数嗅探,统计更新或元数据更改(例如添加新索引),计划是否发生变化,我知道的最佳答案是保持计划稳定plan guides。为已经具有良好执行计划的关键查询部署计划指南可能是强制优化程序继续使用良好,经过验证的计划的最佳方法。见Applying a Fixed Query Plan to a Plan Guide

  

您可以将固定查询计划应用于OBJECT或类型的计划指南   SQL。应用固定查询计划的计划指南在您使用时非常有用   了解现有的执行计划,其执行效果优于   优化程序为特定查询选择的一个。

通常的警告适用于任何可能滥用的功能,阻止优化程序使用可能实际上比计划指南更好的计划。

答案 1 :(得分:1)

以下方法如何:

  • 保存所有典型查询的执行计划。
  • 应用新索引后,请检查哪些执行计划已更改。
  • 使用修改后的计划测试查询的效果。

答案 2 :(得分:0)

从“查询性能调整”页面

Improve Indexes

此页面提供了许多有用的分步提示,介绍如何调整索引以获得最佳性能,以及需要注意的内容(分析)。

  

与大多数性能优化技术一样,存在权衡。例如,使用更多索引,SE​​LECT查询可能会运行得更快。但是,DML(INSERT,UPDATE和DELETE)操作将显着减慢,因为每个操作必须维护更多索引。因此,如果您的查询主要是SELECT语句,则更多索引可能会有所帮助。如果您的应用程序执行许多DML操作,那么您应该对所创建的索引数量保守。

其他资源:

  

但是,请务必记住,非聚集索引会减慢数据修改和插入过程,因此应将索引保持在最低限度

  

SQL Server中的碎片索引和表可能会降低应用程序性能。这是一个在SQL服务器和数据库中查找碎片索引的存储过程。

答案 3 :(得分:0)

好的。首先,索引减慢了两件事(至少)

- > insert / update / delete:index rebuild

- >查询计划:“我应该使用该索引吗?”

有人提到查询计划程序可能会采用效率较低的路由 - 这不应该发生。

如果您的优化器甚至还不错,并且您的统计信息/参数正确,则无法选择错误的计划。

无论哪种方式,在你的情况下(mssql),你很难相信优化器,并且仍然必须每次检查。

您目前正在做的事情听起来很合理,您应该确保您正在查看的数据是相关的,即正确比例的真实用例查询(这可能会造成一个不同的世界)。

为了做到这一点,我总是建议根据实际用途编写基准测试脚本 - 通过记录production-env。查询,有点像我在这里说的那样:

Complete db schema transformation - how to test rewritten queries?