我的查询无法使用"无法为数据库分配新页面' TEMPDB'因为文件组中没有足够的磁盘空间' DEFAULT'"。
在解决问题的过程中,我正在检查执行计划。标记为"聚集索引扫描(Clustered)"有两个代价高昂的步骤。我很难找出这意味着什么?
我很感激对聚合索引扫描(Clustered)"的任何解释。或建议在哪里找到相关文件?
答案 0 :(得分:36)
我很感激“集群索引扫描”的任何解释 (群集)“
我会尝试以最简单的方式,以便更好地理解您需要了解索引搜索和扫描。
SO让我们构建表
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结构直接寻找匹配记录的地方
您可以使用下面的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
并查看执行计划
您已直接在查询中请求了行,这就是您获得聚集索引SEEK的原因。
聚簇索引扫描:当Sql server在聚簇索引中从上到下读取行时。
例如,在非关键列中搜索数据。在我们的表中,NAME是非键列,因此如果我们将在名称列中搜索某些数据,我们将看到clustered index scan
,因为所有行都处于聚簇索引叶级别。
示例
select * from scanseek where name = 'Name340'
请注意:我将此答案简称为更好的理解,如果您有任何问题或建议,请在下面发表评论。
答案 1 :(得分:5)
在评论中扩展了Gordon的答案,聚集索引扫描正在扫描其中一个表索引,以查找您正在执行where子句过滤的值,或者连接到查询计划中的下一个表。
表可以有多个索引(一个是聚簇的,一个是非聚簇的),SQL Server将根据正在执行的过滤器或连接搜索相应的索引。
在MSDN上很好地解释了Clustered Indexes。集群和非集群之间的关键区别在于聚簇索引定义了行在磁盘上的存储方式。
如果您的聚簇索引由于记录数量而非常昂贵,您可能希望在表格中为经常搜索的字段添加非聚集索引,例如用于过滤记录范围的日期字段
答案 2 :(得分:3)
聚簇索引是索引的终端(叶子)节点本身是实际数据页面的索引。每个表只能有一个聚簇索引,因为它指定了如何在数据页中排列记录。它通常(并且有一些例外)被认为是性能最高的索引类型(主要是因为在你到达实际数据记录之前有一个较少的间接级别)。
“聚簇索引扫描”表示SQL引擎在遍历聚簇索引时搜索特定值(或一组值)。它是定位记录的最有效方法之一(通过“聚集索引搜索”节拍,其中SQL引擎希望匹配单个选定值)。
错误消息与查询计划完全无关。它只是意味着你在TempDB上空间不足。
答案 3 :(得分:1)
由于聚集索引扫描,我一直在性能和超时方面遇到问题。但是,另一个看似相同的数据库没有相同的问题。 原来数据库上的COMPATIBILITY_LEVEL标志是不同的... COMPATIBILITY_LEVEL 100的版本正在使用扫描,级别130的数据库未使用扫描。性能差异巨大(同一查询从1分钟以上到不到1秒)
ALTER DATABASE [mydb] SET COMPATIBILITY_LEVEL = 130
答案 4 :(得分:0)
如果将鼠标悬停在查询计划中的步骤上,SSMS将显示该步骤的描述。这将使您对“聚簇索引扫描(聚簇)”和涉及的所有其他步骤有一个基本的了解。