为什么在此查询中进行聚簇索引扫描?

时间:2017-01-26 16:10:59

标签: sql-server sql-server-2012

此查询(SQL2012)执行计划向我显示在PK索引的内部子查询中使用的聚簇索引扫描:

  SELECT n3.id as node_id,x.id as id,
  (select xv.value from xv 
  --with(forceseek)  
  where xv.id=x.id) as [value]
  FROM x
  INNER JOIN n3
  ON x.[obj_id]=n3.id 
  AND n3.parent_id = '975422E0-5630-4545-8CF7-062D7DF72B6B'

表x和xv是master->详细信息表。

当我使用提示forceseek时,它会显示Clustered Index Seek并快速执行查询。 为什么有Scan而不是Seek? 如何更改查询以使索引搜索没有提示FORCESEEK?

UPD: 完整的演示脚本:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
/*
DROP TABLE [dbo].[xv]
DROP TABLE [dbo].[x]
DROP TABLE [dbo].[n3]
*/

CREATE TABLE [dbo].[n3](
    [id] [uniqueidentifier] NOT NULL,
    [parent_id] [uniqueidentifier] NOT NULL,
 CONSTRAINT [PK_n3] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)
)

GO

CREATE TABLE [dbo].[x](
    [obj_id] [uniqueidentifier] NOT NULL,
    [id] [int] IDENTITY(1,1) NOT NULL,
 CONSTRAINT [PK_x] PRIMARY KEY CLUSTERED 
(
    [id] ASC
))

GO

ALTER TABLE [dbo].[x]  WITH CHECK ADD  CONSTRAINT [FK_x_n3] FOREIGN KEY([obj_id])
REFERENCES [dbo].[n3] ([id])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[x] CHECK CONSTRAINT [FK_x_n3]
GO

CREATE TABLE [dbo].[xv](
    [id] [int] NOT NULL,
    [value] [sql_variant] NOT NULL,
 CONSTRAINT [PK_xv] PRIMARY KEY CLUSTERED 
(
    [id] ASC
))

GO

ALTER TABLE [dbo].[xv]  WITH CHECK ADD  CONSTRAINT [FK_xv_x] FOREIGN KEY([id])
REFERENCES [dbo].[x] ([id])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[xv] CHECK CONSTRAINT [FK_xv_x]
GO

INSERT INTO n3(id,parent_id)
select newid(), '975422E0-5630-4545-8CF7-062D7DF72B6B'
GO 10

INSERT INTO n3(id,parent_id)
select newid(), '805422E0-5630-4545-8CF7-062D7DF72B6B'
GO 5

INSERT INTO x([obj_id]) 
select id from n3 where parent_id='975422E0-5630-4545-8CF7-062D7DF72B6B';


insert into xv (id, value) 
select id, cast(RAND(1) as sql_variant) from x 

--select * from x
--select * from n3

  SELECT n3.id as node_id,x.id as id,
  (select xv.value from dbo.xv 
  --with(forceseek)  
  where xv.id=x.id
  ) as [value]
  FROM dbo.x
  INNER JOIN dbo.n3
  ON x.[obj_id]=n3.id
  AND n3.parent_id = '975422E0-5630-4545-8CF7-062D7DF72B6B'


/*
DROP TABLE [dbo].[xv]
DROP TABLE [dbo].[x]
DROP TABLE [dbo].[n3]
*/

--Update statistics xv with fullscan

1 个答案:

答案 0 :(得分:1)

我怀疑statistics表的xv可能已过期。更新xv的统计信息,然后再次尝试运行查询。

Update statistics xv with fullscan

更新:

查看数据设置和查询后,对于给定的parent_id输入,很明显xxv中的所有记录都匹配,因此优化程序选择显而易见索引扫描而不是搜索,因为它已从xxv表中获取所有记录

此外,记录数量较少,因此优化程序更喜欢扫描而不是搜索