2016-01-01 70 views
1

Orders是350k行。 Users是20k行。 Reflinks是2k行。 @p0是40k ids。 SplitIds(@p0)拆分@p0並返回TABLE(Id INT NOT NULL PRIMARY KEY)。看起來像立即執行。加入表值函數減慢查詢

第一個SELECT立即執行並返回7.5k行。其執行計劃完全基於'哈希匹配'塊。

SELECT執行120s並返回相同的7.5k行。其執行平面相同,但基於Nested Loop塊。

是否有可能以某種方式加快第二個查詢?我的任務是明確指定輸入訂單的列表,這就是爲什麼我創建了SplitIds。如果你知道如何做到這一點沒有SplitIds - 你的想法也將得到讚賞。

DECLARE @p0 varbinary(max); 
SET @p0 = 0x.........; // LOT OF BYTES 

SELECT Orders.Id, Reflinks.Rate1 
FROM Orders 
INNER JOIN Users ON Orders.UserId = Users.Id 
INNER JOIN Reflinks ON Users.ReflinkId = Reflinks.Id 

SELECT Orders.Id, Reflinks.Rate1 
FROM SplitIds(@p0) AS t0 
INNER JOIN Orders ON t0.Id = Orders.Id 
INNER JOIN Users ON Orders.UserId = Users.Id 
INNER JOIN Reflinks ON Users.ReflinkId = Reflinks.Id 

回答

1

如果你願意用臨時表,您可以將結果從SplitIds在一個適當的索引臨時表存儲,並使用它,而不是進行第二次查詢。這肯定會加快速度,因爲SQL Server將能夠爲查詢創建更好的執行計劃。

CREATE TABLE #temp(Id INT NOT NULL PRIMARY KEY) 

INSERT INTO #temp(Id) SELECT Id FROM SplitIds(@p0) 

SELECT Orders.Id, Reflinks.Rate1 
FROM #temp AS t0 
INNER JOIN Orders ON t0.Id = Orders.Id 
INNER JOIN Users ON Orders.UserId = Users.Id 
INNER JOIN Reflinks ON Users.ReflinkId = Reflinks.Id 
+1

同意@GuillermoGutiérrez,並且還希望建議嘗試使用表變量,也就像使用唯一約束創建非聚集索引的'@Table'一樣。即使如此,你也可以用上面提到的#table嘗試使用非聚集索引。 –

+1

先生,我試過你的版本。真的行。執行計劃與我的第一個版本相同。但最重要的是,它讓我意識到真正的瓶頸是「SplitIds」本身。 http://stackoverflow.com/q/34556299/758815 – Denis