sql-server-2005 - 我应该怎么做才能获得聚集索引查找而不是聚集索引扫描?

标签 sql-server-2005 clustered-index

我在SQL Server 2005中有一个存储过程,当我运行它并查看它的执行计划时,我注意到它正在执行聚集索引扫描,这使它花费了84%。我读到我必须修改一些东西才能在那里找到聚集索引,但是我不知道要修改什么。

我将不胜感激。

谢谢,

布赖恩

最佳答案

没有任何细节很难猜测出问题是什么,甚至根本就没有问题。选择扫描而不是搜索可能受许多因素驱动:

  • 查询表示覆盖整个表的结果集。 IE。查询是一个简单的SELECT * FROM <table>。这是一个微不足道的情况,可以通过簇状索引扫描完全覆盖,而无需考虑其他任何事情。
  • 优化器没有其他选择:
  • 查询表示整个表的子集,但过滤谓词位于不属于集群键的列上,并且这些列上也没有非聚集索引。除了全面扫描之外,这些都不是替代计划。
  • 查询对聚集索引键中的列具有过滤谓词,但它们不是SARGable。通常需要对过滤谓词进行重写以使其可保存,正确的重写取决于大小写。由于隐式转换规则,例如,可能会出现更细微的问题。过滤谓词为WHERE column = @value,但列为VARCHAR(Ascii),@ value为NVARCHAR(Unicode)。
  • 查询在聚簇键中的列上具有SARGale筛选谓词,但最左边的列未筛选。 IE。 clustred索引位于(foo, bar)列上,但WHERE子句仅位于bar上。
  • 优化器选择进行扫描。
  • 如果备选方案是非聚集索引,则进行扫描(或范围查找),但选择使用聚集索引,则由于查询投影缺乏非聚集索引覆盖范围,通常可以将原因归结为index tipping point 。请注意,这不是您的问题,因为您希望使用聚集索引查找,而不是非聚集索引查找(假设问题是100%准确且已记录...)
  • 基数估计。查询成本估算是基于聚集索引键统计信息的,该统计索引提供对结果基数(即,将匹配多少行)的估计。在简单查询上不会发生这种情况,因为无论统计信息多么差,任何搜索或范围搜索的估计值都将低于用于扫描的估计值,但是在复杂的查询中,如果对多个表进行联接和过滤,更为复杂,并且该计划可能包括在预期会进行搜索的扫描,因为查询优化器可能会选择计划,在该计划上,联接评估顺序被反转为观察者期望的计划。反向顺序选择可能正确(大多数时候)或可能有问题(通常是由于统计信息已过时或参数嗅探)。
  • 订购保证。扫描将以有保证的顺序产生结果,并且执行树上较高的元素可能会从该顺序中受益(例如,可以消除排序或假脱机,或者可以使用合并联接来代替哈希/嵌套联接)。总体而言,由于选择了一条明显较慢的访问路径,查询成本会更高。

  • 这些是一些快速指示,为什么在期望使用聚集索引查找时可能会出现聚集索引扫描。这个问题非常笼统,除了依靠8球之外,不可能给出“为什么”的答案。现在,如果我认为您的问题得到了正确的记录和正确的表达,那么期望聚集索引查找意味着您正在基于聚集的键值搜索唯一记录。在这种情况下,问题必须出在WHERE子句的SARGability上。

    关于sql-server-2005 - 我应该怎么做才能获得聚集索引查找而不是聚集索引扫描?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1359558/

    相关文章:

    sql - 跨实例导入/导出 Sql Server 2005 用户/权限的简便方法?

    sql-server - 与 SQL Server 2005 Enterprise 相比,SQL Server 2005 Express 中的数据库性能是否较慢?

    sql-server-2005 - 如何在 SQL Server 2005 中替换部分 XML 节点

    oracle - 我应该避免使用主键并使用索引的唯一列吗?

    nhibernate - 如何使用 Fluent NHibernate 创建聚集索引?

    sql-server-2005 - 存储过程中的 IF、RAISERROR 和 RETURN

    用于更改所有存储过程中的所有表引用的 SQL 脚本

    sql - 由于 LEFT JOIN 或子查询,无法在 View 上创建 CLUSTERED INDEX

    google-bigquery - 如何提高分区+集群表查询的数据量?

    sql - 聚集索引 - 多部分索引与单部分索引以及插入/删除的影响