为什么我得到聚集索引扫描而不是表扫描?

问题描述 投票:0回答:1

我有这些简单的表,一个没有索引,另一个只有主键和 id 上的聚集索引:

CREATE TABLE [dbo].[MyTableWithoutPk]([id] [int] NOT NULL, [category_id] int NULL)

CREATE TABLE [dbo].[MyTableWithPk]   ([id] [int] NOT NULL, [category_id] int NULL, 
  CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED ([id] ASC))

如果我使用 WHERE 子句执行此查询,我会如预期得到表扫描:

SELECT * FROM [dbo].[MyTableWithoutPk] where [category_id] = 100

enter image description here

如果我对 MyTableWithPk 执行相同的查询,我仍然期望进行表扫描,因为在 Category_id 上没有索引。但我得到了聚集索引扫描!

SELECT * FROM [dbo].[MyTableWithPk] where [category_id] = 100

enter image description here

我错过了什么?

我还检查了SQL中的表扫描和索引扫描,它还说:“如果category_id上没有索引,则将执行表扫描”

sql-server sql-execution-plan database-indexes
1个回答
0
投票

在 SQL Server 中,

Clustered Index Scan
Table Scan
都是读取整个数据集的操作,但它们根据底层表结构访问数据的方式有所不同。

  1. 聚集索引扫描

    • 聚集索引扫描发生在具有聚集索引的表上。
    • 在具有聚集索引的表中,数据按照聚集索引的顺序存储在磁盘上。聚集索引定义表行的物理排序。
    • 执行聚集索引扫描时,SQL Server 按照聚集索引的顺序读取表中的所有行。它本质上是扫描聚集索引来访问数据。
    • 当查询优化器认为按索引顺序读取所有行比使用更具选择性的访问方法(如查找)更有效时,将使用此操作。
  2. 表格扫描:

    • 表扫描发生在没有聚集索引的表上,通常称为堆。
    • 在堆中,数据不以任何特定顺序存储。行将添加到数据页中任何可用空间的位置。
    • 执行表扫描时,SQL Server 会读取表中的所有行,而不会进行任何排序。它直接扫描存储数据的数据页。
    • 当没有聚集索引来指导读取操作时,或者当查询需要访问大部分行并且没有有用的非聚集索引时,使用此操作。

主要区别

  • 底层结构:主要区别在于底层表结构。聚集索引扫描基于聚集索引的排序顺序,而表扫描则读取堆中的数据,没有任何特定顺序。
  • 性能:聚集索引扫描有时比表扫描更高效,因为数据以排序方式存储,这对于某些类型的查询可能是有益的。但是,如果查询需要读取整个表,则这两种操作在性能方面的成本可能相似。
  • 使用场景:聚集索引扫描和表扫描之间的选择取决于聚集索引的存在和查询的性质。 SQL Server 查询优化器根据查询执行计划自动选择最有效的方法。
© www.soinside.com 2019 - 2024. All rights reserved.