2017-03-05 176 views
1

我有2個表SQL Server的執行計劃問題

CREATE TABLE [dbo].[T2] (
    [Id] INT   IDENTITY (1, 1) NOT NULL, 
    [F1] NVARCHAR (100) NULL, 
    [F2] NVARCHAR (100) NULL, 
    [F3] NVARCHAR (MAX) NULL, 
    PRIMARY KEY CLUSTERED ([Id] ASC) 
); 

GO 
CREATE NONCLUSTERED INDEX [IX_T2_F1_F2] 
    ON [dbo].[T2]([F1] ASC, [F2] ASC); 

CREATE TABLE [dbo].[T3] (
    [Id] INT   IDENTITY (1, 1) NOT NULL, 
    [F1] NVARCHAR (100) NULL, 
    [F2] NVARCHAR (100) NULL, 
    [F3] NVARCHAR (MAX) NULL, 
    PRIMARY KEY CLUSTERED ([Id] ASC) 
); 

GO 
CREATE NONCLUSTERED INDEX [IX_T3_F1_F2] 
    ON [dbo].[T3]([F1] ASC, [F2] ASC) 
    INCLUDE([F3]); 

這些都是我的執行計劃

enter image description here

的問題是,爲什麼查詢# 2的執行計劃不是Index Seek (NonClustered),爲什麼查詢優化器選擇掃描c關於PK的索引,而不是非聚集索引{F1,F2}

更新#1:

Query #2 Stats

+0

你可能在這些表中有0行,所以沒關係。在那裏放置一百萬行並更新你的統計數據。 –

+0

@ ta.speot.is我在這兩個表中都有100k行 – dizar47

+0

那麼執行計劃中的那些箭頭非常窄 - SQL Server估計有多少行? –

回答

2

SELECT [F1],[F2],[F3] FROM [T2] WHERE ...需要三列,IX_T2_F1_F2只包含其中兩個。

當涉及到覆蓋索引的時候,SQL Server有時候並不能滿足所有需要的列。爲了滿足查詢,它必須使用覆蓋索引和聚集索引,並且(簡化一點)涉及的操作越多,查詢成本就越高。

它估計掃描一個索引(聚集索引)比使用兩個索引便宜,你得到一個聚集索引掃描的計劃。

Here是一篇文章,它進一步討論了它,以及SQL Server將在何處使用覆蓋索引和聚集索引。

+0

我依稀記得布倫特·奧扎爾有一篇關於覆蓋索引的更好的文章,爲什麼他們有時會被忽略,但我找不到它。 –

1

這可能是你的統計數據沒有及時更新。您可以使用查詢提示來強制SQL Server使用您的首選索引,例如(index(your_index_name))。我會建議嘗試這個查詢提示來檢查你的索引的性能。