为什么/何时/如何选择整个聚簇索引扫描而不是全表扫描?

时间:2010-10-19 16:20:45

标签: sql-server database performance indexing clustered-index

IMO,请纠正我...
  聚集索引的叶子包含实际的表行,所以带有中间叶子的完整聚簇索引包含的数据比完整表格多得多(?)
为什么/何时/如何在整个表扫描中选择整个聚簇索引扫描?

SELECT查询中使用的CUSTOMER_ID列上的聚簇索引如何在SELECT列表或WHERE条件[1]中不包含它?

更新:
我是否应该理解完整的群集扫描比全表扫描更快,因为“每个数据页都包含指向下一个和上一个叶节点页面的指针,因此扫描不需要使用索引中的更高级别的页面”?
是否还有其他原因(非参与查询)聚类索引用于排序?

UPDATE2:
由于事后的想法,连续访问不能提高性能,而通过IAM指针加载表可以并行化 聚簇索引扫描是否意味着连续页面读取?
群集表是否表示没有IAM指针(全表扫描不可能)? 为什么群集表不能被全表扫描?
我仍然不明白为什么/为什么聚簇索引全扫描可以比全表扫描“更好” 这是否意味着拥有聚集索引会导致性能恶化?

问题是关于聚簇表而不是堆(非索引)表。

UPDATE3:
“完全聚集索引扫描”真的是“全表扫描”的同义词吗? 有什么区别?

[1]索引覆盖提升SQL Server查询性能
http://www.devx.com/dbzone/Article/29530

3 个答案:

答案 0 :(得分:2)

聚簇索引 - 或者更确切地说:它的叶子页 ARE 表数据 - 因此聚簇索引扫描实际上与表扫描相同(对于具有聚簇索引的表)。 / p>

如果你没有聚集索引,那么你的表就是一个堆 - 显然,在这种情况下,如果你需要查看所有数据,你就不能进行聚簇索引扫描,因为没有聚簇索引,所以你最终会得到一个表扫描,它只触及那个堆表的所有数据页。

答案 1 :(得分:2)

聚集索引的叶级别是表。 “表扫描”是指没有聚簇索引的堆。

每个数据页面都包含指向下一个和上一个叶节点页面的指针,因此扫描不需要使用索引中的更高级别页面。

答案 2 :(得分:0)

请在“无法直接访问群集表中的数据行 - 为什么?”,首先阅读我的回答。

“聚集索引的叶子包含实际的表行,所以带有中间叶子的完整聚簇索引包含比完整表(?)”

更多的数据

看到你正在将“表”与存储结构混合在一起。在你的问题的背景下,例如。考虑CI的大小而不是“表”,那么你必须考虑CI减去叶级(这是数据行)。仅CI,索引部分很小。中间级别(如任何B树)包含部分(非完整)密钥条目;它排除了最低级别,即完整的密钥条目,它位于行本身,并且不会重复。

表(完整CI)可能是10GB。 CI仅为10MB。有很多可以从10MB确定,而不必去100GB。

理解:同一个表(CI)上的等效NCI可能是22MB;如果删除CI,则同一个NCI在同一个表上可能是21.5MB(假设CI密钥合理,不宽胖)。

“为什么/何时/如何在整个表扫描中选择整个聚簇索引扫描?”

经常。在上下文中,我们正在谈论CI-minus-Leaf水平。对于仅使用CI中的列的查询,CI中的那些列(实际上是任何索引)的存在允许查询成为“覆盖查询”,这意味着它可以完全从索引服务,无需去到数据行。思考部分键的范围扫描:BETWEEN x和yY; x< = y;等

(当认为它应该选择索引扫描时,优化器总是有可能选择一个表扫描,这是一个不同的故事。)

“我仍然不明白为什么/为什么聚集索引全扫描比全表扫描”更好“。”

(MS使用的术语不如我的答案精确。)对于任何可以从10MB CI回答的查询,我宁愿通过数据缓存流失10MB,而不是100GB。对于相同的查询,以CI键上的范围为界,这只是10MB的一小部分。

对于需要“全表扫描”的查询,是的,您必须阅读CI的所有Leaf页面,即100GB。