“群集索引扫描(群集)”对SQL Server执行计划意味着什么?

问题描述 投票:18回答:4

我有一个查询无法执行“无法为数据库'TEMPDB'分配新页面,因为文件组'DEFAULT'中的磁盘空间不足”。

在解决问题的方式我正在检查执行计划。有两个标记为“聚集索引扫描(聚集)”的昂贵步骤。我很难找出这意味着什么?

我将不胜感激“Clustered Index Scan(Clustered)”的任何解释或有关在何处查找相关文档的建议?

sql sql-server sql-execution-plan
4个回答
43
投票

我将不胜感激“Clustered Index Scan(Clustered)”的任何解释

我将尝试以最简单的方式,以便更好地理解您需要了解索引搜索和扫描。

所以我们可以构建表格

use tempdb GO


create table scanseek  (id  int , name varchar(50) default ('some random names')  )

create clustered index IX_ID_scanseek on scanseek(ID)


declare @i int
SET @i = 0
while (@i <5000)
begin 
insert into scanseek
select @i, 'Name' + convert( varchar(5) ,@i)
set @i =@i+1
END

索引查找是SQL服务器使用索引的b-tree结构直接查找匹配记录的位置

enter image description here

您可以使用下面的DMV检查表根和叶节点

-- check index level 
SELECT 
index_level
,record_count
,page_count

,avg_record_size_in_bytes
FROM sys.dm_db_index_physical_stats(DB_ID('tempdb'),OBJECT_ID('scanseek'),NULL,NULL,'DETAILED')
GO

现在我们在列“ID”上有聚簇索引

让我们寻找一些直接匹配的记录

select * from scanseek where id =340

并查看执行计划

enter image description here

您已经在查询中直接请求了行,这就是您获得聚簇索引SEEK的原因。

聚簇索引扫描:当Sql server在聚簇索引中从上到下读取行时。例如,在非关键列中搜索数据。在我们的表中,NAME是非键列,因此如果我们将在名称列中搜索某些数据,我们将看到clustered index scan,因为所有行都处于聚簇索引叶级别。

select * from scanseek where name = 'Name340'

enter image description here

请注意:我的答案简短,仅为了更好的理解,如果您有任何问题或建议,请在下面评论。


5
投票

在注释中扩展了Gordon的答案,聚簇索引扫描正在扫描其中一个表索引,以查找您正在执行where子句过滤的值,或者连接到查询计划中的下一个表。

表可以有多个索引(一个是聚簇的,一个是非聚簇的),SQL Server将根据正在执行的过滤器或连接搜索相应的索引。

Clustered Indexes在MSDN上得到了很好的解释。集群和非集群之间的关键区别在于聚簇索引定义了行在磁盘上的存储方式。

如果由于记录数量而导致聚簇索引的搜索成本非常高,则可能需要在表中为经常搜索的字段添加非聚集索引,例如用于筛选记录范围的日期字段。


3
投票

聚簇索引是索引的终端(叶)节点是实际数据页本身的索引。每个表只能有一个聚簇索引,因为它指定了如何在数据页中排列记录。它通常(并且有一些例外)被认为是性能最高的索引类型(主要是因为在您到达实际数据记录之前,间接级别较少)。

“聚簇索引扫描”表示SQL引擎正在遍历聚簇索引以搜索特定值(或一组值)。它是定位记录的最有效方法之一(通过“聚集索引搜索”节拍,其中SQL引擎希望匹配单个选定值)。

该错误消息与查询计划完全无关。它只是意味着你在TempDB上空间不足。


0
投票

如果将鼠标悬停在查询计划中的步骤上,SSMS将显示该步骤的描述。这将使您对“聚集索引扫描(聚集)”以及所涉及的所有其他步骤有基本的了解。

© www.soinside.com 2019 - 2024. All rights reserved.