非聚集索引的索引访问

时间:2010-08-10 23:29:57

标签: sql-server optimization

如果我有两个数据表。一个有聚簇索引CINDEX,另一个是堆HEAP。

两者在同一列上也有一个非聚集索引 - SEARCHCOL

假设我的聚簇索引列与rowid的大小相同,因此两个非聚集索引的深度都是相同的。

获取表格行需要更少的I / O ...

a) SELECT * FROM CINDEX WHERE SEARCHCOL = :1

b) SELECT * FROM HEAP WHERE SEARCHCOL = :1

选择a或b 解释为什么 陈述任何假设

1 个答案:

答案 0 :(得分:2)

如果Searchcol具有足够的选择性,那么计划应该执行预期的搜索到非聚集索引(两者之间相同),然后查找聚簇索引或堆以获取所有列满足*预测。与BTree搜索相比,稍后查找将更快(在页面中直接搜索:slot)(必须在包含该行的叶子页面上打1-2个非叶页面)如果堆行是没动了。如果移动了堆行,则查找必须在新页面上追踪转发指针,这意味着新的逻辑读取IO,依此类推,直到找到该位置(如果它多次移动)。因此,通常堆将节省1-2个逻辑读取IO(查找中的查找的非叶部分)。

如果SEARCHCOL没有足够的选择性并且查询命中Tipping Point那么所有的赌注都会关闭,因为一个计划将按键顺序进行聚簇索引扫描,而另一个计划将按分配顺序进行堆扫描(他们最终会得到大致相同的IO)。

但是我必须警告说,在做出关于堆与BTree的决定时,这种细节测量(1-2页IO)是不健康的。我的看法是总是选择BTree,除非有明确的理由不。显而易见的原因通常是INSERT性能(这是HEAP围绕BTrees运行的地方),这意味着ETL数据加载场景,其中数据被加载到堆中以实现快速上载性能,然后堆变为聚簇索引并添加了将operaiton切换到大事实表。