此查询(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
答案 0 :(得分:1)
我怀疑statistics
表的xv
可能已过期。更新xv
的统计信息,然后再次尝试运行查询。
Update statistics xv with fullscan
更新:
查看数据设置和查询后,对于给定的parent_id
输入,很明显x
和xv
中的所有记录都匹配,因此优化程序选择显而易见索引扫描而不是搜索,因为它已从x
和xv
表中获取所有记录
此外,记录数量较少,因此优化程序更喜欢扫描而不是搜索