想象一下Foo 表在 ColA 和 ColB 上具有非聚集索引,在 ColC、ColD 上没有索引
SELECT colA, colB
FROM Foo
大约需要30 秒。
SELECT colA, colB, colC, colD
FROM Foo
大约需要2 分钟。
Foo 表有超过 500 万行。
问题:是否包含不属于索引的列会减慢查询速度?如果是,为什么?-它们不是已经阅读的页面的一部分吗?
想象一下Foo 表在 ColA 和 ColB 上具有非聚集索引,在 ColC、ColD 上没有索引
SELECT colA, colB
FROM Foo
大约需要30 秒。
SELECT colA, colB, colC, colD
FROM Foo
大约需要2 分钟。
Foo 表有超过 500 万行。
问题:是否包含不属于索引的列会减慢查询速度?如果是,为什么?-它们不是已经阅读的页面的一部分吗?
如果您编写使用覆盖索引的查询,则不会访问堆/聚集索引中的完整数据页。
如果您随后向查询中添加更多列,使得索引不再覆盖,那么将发生额外的查找(如果仍然使用索引),或者您完全强制使用不同的数据访问路径(例如使用表扫描而不是使用索引)
自 2005 年以来,SQL Server 就支持索引中包含列的概念。这包括索引叶子中的非键列 - 因此它们在索引使用的数据查找阶段没有用,但仍然有助于避免在堆/聚集索引中执行额外的查找,如果他们'足以使该指数成为覆盖指数。
此外,将来,如果您想更好地了解为什么一个查询快而另一个查询慢,请查看生成执行计划,然后您可以进行比较。
即使你不理解所使用的术语,你至少应该能够玩它们之间的“spot the difference”,然后根据术语进行搜索(例如表扫描、索引查找或查找)
简单的答案是:因为非聚集索引不与数据存储在同一页中,所以 SQL Server 必须查找实际的数据页来获取其余部分。
非聚集索引存储在单独的数据结构中,而聚集索引存储在与实际数据相同的位置。这就是为什么您只能拥有一个聚集索引。