2017-01-26 92 views
2

該查詢(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 
+0

如果您正在與表中的每一行進行交互,我會想象查詢優化器將使用掃描搜索。另外,如果您複製/粘貼查詢並同時運行這兩個查詢,一個使用forceseek,另一個使用它,您將看到掃描的相對成本較低。 – dfundako

+0

真實表中有10 * 100萬行。我的問題是,真正的查詢(掃描)執行3-5秒,這是死鎖的原因。如果我使用提示FORCESEEK,它會工作<1秒,死鎖消失。 – Oleg

回答

1

我懷疑statisticsxv的表可能是過時的。更新xv的統計信息並嘗試再次運行查詢。

Update statistics xv with fullscan 

更新:

看數據建立和查詢後,對於給定的parent_id輸入是很清楚,在這兩種xxv匹配的所有記錄,這樣很明顯,優化選擇索引掃描,而不是尋找,因爲它已經從xxv獲取所有記錄表

此外,記錄數量更少,所以優化器將更喜歡掃描而不是查找

+0

我試過了 - 沒有變化。我已經添加了完整的演示腳本(參見第1條消息),它在3個新表格上演示了這一點。 – Oleg

+0

@Oleg - 檢查更新 –

+0

請參閱我上面的評論。 – Oleg

相關問題