我想要從一些SQL查詢中獲得一些額外的性能,這些查詢在一個非獨特的非集羣索引,它也是表A中的外鍵。該外鍵是表B上的主鍵,並且是聚集索引。關於非聚集索引Vs的where子句額外連接和where子句的聚集索引
我想知道的是,如果我添加從表A到表B的連接,並且在聚集索引的字段上有where子句(與非聚集索引相反),我會獲得性能增益沒有額外的連接)?
感謝
我想要從一些SQL查詢中獲得一些額外的性能,這些查詢在一個非獨特的非集羣索引,它也是表A中的外鍵。該外鍵是表B上的主鍵,並且是聚集索引。關於非聚集索引Vs的where子句額外連接和where子句的聚集索引
我想知道的是,如果我添加從表A到表B的連接,並且在聚集索引的字段上有where子句(與非聚集索引相反),我會獲得性能增益沒有額外的連接)?
感謝
我不這麼認爲,如添加另一個表將涉及更多的讀取。但是你必須測試。
否按照Frank的說法,這需要從表B中讀取更多頁面。您說您已對執行過濾的外鍵擁有NC索引。你也可以考慮用FK(B的PK)來衡量表A的聚集優點和缺點 - 如果你通常總是通過在B上過濾來獲取表A,那麼這可以減少在A上獲取的頁的數量(但顯然,可能會有其他的查詢可能會受到這個影響,這可以算作對此)
要真正消除多餘的性能,你最好確保你的非唯一的非聚集索引是一個covering index(即索引包含滿足查詢所需的所有列)。您可以利用SQL 2005中引入的included columns這一概念來幫助您做到這一點。
如果您考慮連接的工作方式 - 它必須在表A中搜索FK列以滿足連接條件 - 這是您似乎試圖避免的掃描。所以我不相信這有可能改善表現。
我做了一些測試。我有兩個表 - tableA(~3000行)和tableB(~200行)。他們都有專欄ID。表A:ID-pk,表B:ID -fk,非聚集索引。
選擇從一個表:
SELECT
a.ID
FROM
dbo.TableA a
WHERE
a.ID IN (1,5,7,9,23,45,56,546,67,32,54,676)
- 執行計劃:
|--Index Seek(OBJECT:([Database].[dbo].[TableA].[IX_TableA_ID] AS [a]), SEEK:([a].[ID]=(1) OR [a].[ID]=(5)) ORDERED FORWARD)
- 統計IO:
Table 'TableA'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
選擇使用兩個表(內部連接)
SELECT
t.ID
FROM
dbo.TableA a
INNER JOIN
dbo.TableB t with(index(PK_TableBs)) ON t.ID = a.ID
WHERE
t.ID IN (1,5,7,9,23,45,56,546,67,32,54,676)
- 執行計劃:
|--Nested Loops(Inner Join, OUTER REFERENCES:([t].[ID]))
|--Clustered Index Seek(OBJECT:([Database].[dbo].[TableB].[PK_TableB] AS [t]), SEEK:([t].[ID]=(1) OR [t].[ID]=(5)) ORDERED FORWARD)
|--Index Seek(OBJECT:([Database].[dbo].[TableA].[IX_TableA_ID] AS [a]), SEEK:([a].[ID]=[Database].[dbo].[TableB].[ID] as [t].[ID]), WHERE:([Database].[dbo].[TableA].[ID] as [a].[ID]>=(1) AND [Database].[dbo].[TableA].[ID] as [a].[ID]<=(5)) ORDERED FORWARD)
- STATISTICS IO:
Table 'TableA'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TableB'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
結果:
針對第一個查詢(33%),第二個查詢成本爲67%(相對於批處理)。 另外,第二個查詢需要更多的讀取。
PS。這是骯髒的快速例子,你應該檢查你自己的。