2

我有以下表格架构 -

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

但是,当我运行以下查询时,我期望 Table Scan as NAME 列没有任何索引:

SELECT * FROM TEST_TABLE WHERE NAME LIKE 'a%'

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

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

我相信,这是因为聚集索引驻留在数据页上而发生的。

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

4

5 回答 5

3

聚集索引是存储所有表数据的索引。所以表扫描和聚集索引扫描是一样的。

在没有聚集索引(“堆”)的表中,表扫描需要爬取所有数据页。这就是查询优化器所说的“表扫描”。

于 2012-09-27T06:24:58.133 回答
3

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

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

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

SELECT * 
FROM TEST_TABLE 
WHERE TEST_TABLE_ID = 34 ;

它执行聚集索引搜索而不是扫描。它不必搜索(扫描)整个表(聚集索引),它直接进入点(搜索)并检查是否id=34存在一行。

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

于 2012-09-27T06:39:22.110 回答
2

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

于 2012-09-27T06:24:57.903 回答
1

这是因为该表有一个聚集索引,它会扫描整个聚集索引以返回基于 where 子句的所有行。您应该如何看到丢失的索引消息。

于 2012-09-27T06:30:50.663 回答
0

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

但是,当您看到聚集索引扫描运算符时,这可能有点误导。如果满足某些条件(相当于 SQL Server 不关心数据的顺序),那么 SQL Server 仍然能够执行无序分配扫描,这更像是表扫描而不是聚集索引扫描,因为它实际上基于 IAM 链按分配顺序读取 CI 的叶级别(表数据页),而不是遵循索引中的指针。这可能会给您带来性能改进,因为碎片(页面不按物理顺序)不会降低性能

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

于 2012-09-27T06:52:41.227 回答