2015-03-19 63 views
1

我有一個存儲過程,它依次調用35個Inline table valued functions(TVF)。T-SQL中的並行處理

所有這些內聯TVF都會返回dbo.Match函數的計算結果表。

這裏的問題是,儘管所有適當的索引都已到位,但只有當較早的一個完成其結果時纔會調用下一個Inline TVF,因此需要相當長的時間。我想要一種方式來並行執行這些操作,以便不必等待其他操作完成,也可以將它們轉換爲適合性能和並行處理的程序或任何其他信封。

由於dbo.Match功能是通用於所有計算和基於來自在線TVF聲明傳遞的參數結果,我相信,如果在sql過的threads概念將被同步。 那麼,是否有任何可用的解決方法來減少執行時間?

我已經附加了一些一段代碼給的,我說的是什麼清晰的概念:

 if @firstname is not null 
     begin 
     SELECT @constVal = FunctionWeight 
    FROM dbo.FunctionWeights WHERE FunctionWeights.FunctionId = 1; 
     INSERT INTO #Temp2 
    (RowNumber,ValFromUser,ColumnName,ValFromFunc,FuncWeight,percentage) 
    SELECT RowNumber,@firstname,'firstname',PercentMatch,@constVal,PercentMatch * @constVal  FROM dbo.MatchFirstName(@firstname, @checkbool) 
    END 



if @Middlename is not null 
    BEGIN 
     SELECT @constVal = FunctionWeight FROM dbo.FunctionWeights 
WHERE FunctionWeights.FunctionId = 2; 
    INSERT INTO #Temp2 (RowNumber,ValFromUser,ColumnName,ValFromFunc,FuncWeight,percentage) 
     SELECT RowNumber, @MiddleName,'Middlename',PercentMatch, @constVal,PercentMatch * @constVal 
     FROM dbo.MatchMiddleName(@MiddleName, @checkbool) 
END 
+0

在sql中,你指定了你想要的結果,而不是應該如何獲取結果。如果你想讓事情並行發生,你需要停止使用過程邏輯(多語句,IF,WHILE等),並根據集合(即單個查詢)進行編寫。如果SQLServer確定它是實現它的最佳方法,它將並行運行它。 – adrianm 2015-03-19 07:22:02

回答

5

在SQL中,你告訴系統你想,不什麼怎麼辦呢 。你最好通過給它整個查詢來優化,然後讓它解決問題。所以,你會做這樣的事情:

INSERT INTO #Temp2 
(RowNumber,ValFromUser,ColumnName,ValFromFunc,FuncWeight,percentage) 
SELECT RowNumber,@firstname,'firstname', 
     PercentMatch,fw1.FunctionWeight, 
     PercentMatch * fw1.FunctionWeight 
FROM dbo.FunctionWeights fw1 
     CROSS JOIN 
     dbo.MatchFirstName(@firstname, @checkbool) mfn 
WHERE 
    fw1.FunctionId = 1 AND 
    @firstname is not null 
UNION ALL 
SELECT RowNumber, @MiddleName,'Middlename', 
     PercentMatch, fw2.FunctionWeight, 
     PercentMatch * fw2.FunctionWeight 
FROM dbo.FunctionWeights fw2 
     CROSS JOIN 
     dbo.MatchMiddleName(@MiddleName, @checkbool) mmn 
WHERE 
    fw2.FunctionId = 2 AND 
    @MiddleName IS NOT NULL 
UNION ALL 
... 

等等 - 只是不斷加入到這個大UNION ALL查詢,結合所有的SELECT S的每個查詢,並嘗試與WHERE子句條件,以取代IF邏輯。

對於傳遞給函數的參數依賴於來自其他表的參數的更復雜查詢,您可能還需要考慮使用CROSS APPLY而不是CROSS JOIN或更復雜的連接條件。

+0

哇:)我很高興我學到了這個技巧。我還有最後一個簡單的問題,希望你回答這個問題。字段像FirstName,LastName和另外33個這樣的字段被用作搜索的基礎,就像我上面提到的那樣。但是,爲所有這些創建單獨的索引並不是一個好主意。那麼,有什麼建議可以避免完整的表掃描? @Damien_The_Unbelever – Simran 2015-03-19 14:28:01

+0

這對於Union All的幾個查詢來說效果很好,但只要超過20點,表現就會受到影響。實際上有35個參數,它的工作速度比順序方法還要慢。任何想法爲什麼是這樣? – Simran 2015-03-19 17:08:04

+0

@Simran - 如果這是一個廣義的搜索例程(對不起,沒有拿起那種類型的上下文),那麼你可能應該閱讀[T-SQL中的動態搜索條件](http:// www。 sommarskog.se/dyn-search.html)由Erland Sommarskog提供。它涵蓋了很多細節。 – 2015-03-19 17:51:51