繁体   English   中英

SQL Server:为什么聚集索引扫描而不是表扫描?

[英]SQL Server: Why Clustered Index Scan and not Table Scan?

我有以下表格架构 -

CREATE TABLE [dbo].[TEST_TABLE]
(
    [TEST_TABLE_ID] [int] IDENTITY(1,1) NOT NULL,
    [NAME] [varchar](40) NULL,
    CONSTRAINT [PK_TEST_TABLE] PRIMARY KEY CLUSTERED 
    (
        [TEST_TABLE_ID] ASC
    )
)

我在TEST_TABLE插入了大量数据。

由于我已将TEST_TABLE_ID列标记为主键,因此将在TEST_TABLE_ID上创建聚簇索引。

当我运行以下查询时,执行计划显示预期的Clustered Index Scan

SELECT * FROM TEST_TABLE WHERE TEST_TABLE_ID = 34

但是,当我运行以下查询时,我期待表扫描,因为NAME列没有任何索引:

SELECT * FROM TEST_TABLE WHERE NAME LIKE 'a%'

但在执行计划中,它显示了Clustered Index Scan

由于NAME列没有任何索引,为什么它正在访问聚簇索引?

我相信,随着聚集索引驻留在数据页面上,这种情况正在发生。

谁能告诉我我的假设是否正确? 或者还有其他原因吗?

聚簇索引是存储所有表数据的索引。 因此,表扫描与聚簇索引扫描相同。

在没有聚簇索引(“堆”)的表中,表扫描需要爬行所有数据页。 这就是查询优化器调用“表扫描”的内容。

正如其他人已经解释的那样,对于具有聚簇索引的表,聚簇索引扫描意味着表扫描

换句话说, 该表是聚集索引。

你的错误是你的第一个查询执行计划:

SELECT * 
FROM TEST_TABLE 
WHERE TEST_TABLE_ID = 34 ;

它执行Clustered Index Seek而不是Scan。 它没有搜索( 扫描 )整个表(聚集索引),它直接进入点( 寻求 ),如果有一排检查id=34存在。

您可以在SQL-Fiddle中看到一个简单的测试,以及两个执行计划的不同之处。

该表存储聚簇索引。 扫描表的唯一方法是扫描聚簇索引。 只有没有聚集索引的表本身才能有“表扫描”。

这是因为该表具有聚簇索引,它将扫描整个聚簇索引以返回基于where子句的所有行。 你应该怎么看到丢失的索引消息。

当您在表上构建群集索引时,SQL Server会根据群集索引键(在您的情况下为Test_Table_ID)逻辑地对该表的行进行排序。

但是,当您看到聚集索引扫描运算符时,这可能会产生一些误导。 如果满足某些条件(等同于SQL Server不关心数据的顺序),则SQL Server仍然能够执行无序分配扫描,这与表扫描比聚簇索引扫描更相似,因为它实际上,基于IAM链,按照分配顺序读取CI的叶级(表数据页),而不是跟随索引中的指针。 这可能会提高性能,因为碎片(页面超出物理顺序)不会降低性能

要查看是否发生这种情况,请查看执行计划中的Ordered属性。 如果将其设置为False,则您将进行无序分配扫描。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM