該查詢(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是主 - >細節的表格。
當我使用提示forceseek時,它顯示聚集索引查找和查詢執行速度很快。 爲什麼有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
如果您正在與表中的每一行進行交互,我會想象查詢優化器將使用掃描搜索。另外,如果您複製/粘貼查詢並同時運行這兩個查詢,一個使用forceseek,另一個使用它,您將看到掃描的相對成本較低。 – dfundako
真實表中有10 * 100萬行。我的問題是,真正的查詢(掃描)執行3-5秒,這是死鎖的原因。如果我使用提示FORCESEEK,它會工作<1秒,死鎖消失。 – Oleg