2010-08-10 59 views
1

如果我有两个数据表。一个是聚簇索引CINDEX,另一个是堆堆。通过非聚集索引访问索引

而且都使用同一列的非聚集索引 - SEARCHCOL

假设我的聚集索引列是大小相同的ROWID,因此这两个非聚集索引的深度是一样的。

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

a) SELECT * FROM CINDEX WHERE SEARCHCOL = :1 

b) SELECT * FROM HEAP WHERE SEARCHCOL = :1 

选择a或b 解释为什么 状态的任何假设

回答

2

如果Searchcol有足够的选择性,则计划应该对非聚集索引(两者相同)进行预期查找,然后查找聚簇索引或堆以便获得满足*投影的所有列。与BTree搜索相比,后续查找在堆中更快(直接搜索页:插槽)(必须打1-2个非叶页才能登陆包含该行的叶页)如果堆行未移动。如果堆行被移动,则查找必须在新页面上追踪转发指针,这意味着新的逻辑读取IO,等等,直到它找到位置(如果它多次移动)。所以一般来说堆会节省1-2个逻辑读IO(查找中查找的非叶部分)。

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

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

+0

也许这是普通SQL Server数据库中的一个细节......但我用高性能数据库调整了一个或两个IO。我想在问题上应该有一个单选按钮......(x)我需要一个企业大男孩的答案或()我有一个部门应用程序与少数用户,没有真正的SLA。但是,我再次感谢你确认我的怀疑。行越宽,每块叶子的行数越少,b-tree表越深,堆越多,“不显眼”的IO就会出现,越多的行越多,越深......再宽或长的表得到比较恶劣。 – 2010-08-10 23:55:16

+0

只需要清楚它不是单个查询中的一个或两个IO ......这是每分钟执行10000次查询的时间。 – 2010-08-10 23:56:09

+0

够公平的。比较使用聚集索引和堆组织的表格:http://msdn.microsoft.com/en-us/library/cc917672.aspx – 2010-08-10 23:59:30