2015-10-15 28 views
3

我有一個查詢使用多個包含不同WHERE子句的SELECT語句來返回多列,以獲得不同類別中的訂單數。我目前正在使用cte來嘗試優化它,但它仍然運行得非常慢。我想一個臨時表可能是一個更快的解決方案,但我有麻煩有:優化使用多個SELECT語句並返回一個結果集的SQL查詢

查詢:

DECLARE @User AS VARCHAR(50) 
SET @User = 'test.user'; 

WITH cte AS (
SELECT 
    o.db_OrderNo, 
    o.db_Deferral, 
    d.db_SeqNo, 
    d.db_Task 
FROM 
    tblOrders o 
    LEFT JOIN tblDate d on d.db_SeqNo = o.db_Status 
    LEFT JOIN tblUserProfile up on up.db_UserId = o.db_RTS 
WHERE 
    o.db_Deleted = 0 
    AND db_Date39 = '1900/01/01' 
    AND d.db_Task IN (1, 2, 3, 4) 
    AND up.db_Email LIKE @User + '%' 
) 
SELECT 
(SELECT COUNT(DISTINCT db_OrderNo) 
    FROM cte 
    WHERE db_Task = 1 
    AND db_Deferral = 0) OrderInEvalCount, 
(SELECT COUNT(DISTINCT db_OrderNo) 
    FROM cte 
    WHERE db_Task = 2 
    AND db_Deferral = 0) OrderInDfcCount, 
(SELECT COUNT(DISTINCT db_OrderNo) 
    FROM cte 
    WHERE db_Task IN (3, 4) 
    AND db_SeqNo NOT IN (37, 39) 
    AND db_Deferral = 0) OrderWipCount, 
(SELECT COUNT(DISTINCT db_OrderNo) 
    FROM cte 
    WHERE db_Deferral != 0) OrderInPendedCount 

輸出:

OrderInEvalCount | OrderInDfcCount | OrderWipCount | OrderInPendedCount 
     20     34    9     2 

臨時表:

CREATE TABLE #TempCounts (OrderInEvalCount int, OrderInDfcCount int, OrderWipCount int, OrderInzPendedCount int); 

// First column 

SELECT COUNT(DISTINCT db_OrderNo) 
    INTO //Not sure how to specify a column 
    FROM tblOrders o 
    WHERE db_Task = 1 
    AND db_Deferral = 0 
    AND o.db_Deleted = 0 
    AND db_Date39 = '1900/01/01' 
    AND up.db_Email LIKE @User + '%' 

我之前沒有使用過TEMP表,所以這個開始可能有點關閉。任何你認爲可以加快當前查詢的其他解決方案將不勝感激。由於

回答

1

可以使用條件爲聚集在外選擇:

SELECT COUNT(DISTINCT (CASE WHEN db_Task = 1 AND db_Deferral = 0 THEN db_OrderNo 
         END)) as OrderInEvalCount, 
     COUNT(DISTINCT (CASE WHEN db_Task = 2 AND db_Deferral = 0 THEN db_OrderNo 
         END)) as OrderInDfcCount, 
     COUNT(DISTINCT (CASE WHEN db_Task IN (3, 4) AND db_SeqNo NOT IN (37, 39) AND 
           db_Deferral = 0 THEN db_OrderNo 
         END)) as OrderWipCount, 
     COUNT(DISTINCT (CASE WHEN db_Deferral <> 0 THEN db_OrderNo 
         END)) as OrderInPendedCount 
FROM cte; 

SQL Server中的一種特殊的方式處理熱膨脹係數:它插入CTE定義成每次看到它的地方查詢。所以,你的版本四次運行CTE的代碼。雖然SQL Server可以優化查詢,但它不能識別出四個塊正在做同樣的事情。 。 。所以它做了更多的工作。

當在查詢中僅引用一次CTE時,則使用CTE對性能沒有影響。

+0

是的,這也是工作太......不知道你可以把表達式放進這樣的計數......每天學點東西 – cocogorilla

+0

工程就像一個魅力,謝謝!在第二個「CASE」的'db_Deferral = 0'之後有一個額外的圓括號。我無法編輯一個字符。 – cfly24

0

我建議在查詢上工作,以便它可以在db_OrderNo上分組以刪除不同。

然後,您的select語句可以在不同訂單號的整個主體上對案例語句進行求和。

select sum(case when db_Task = 1 and db_Deferral = 0 then 1 else 0 end) OrderInEvalCount 
    , sum(case when db_Task = 2 and db_Deferral = 0 then 1 else 0 end) OrderInDfcCount 
    , sum(case when db_Task in (3, 4) and db_SeqNo not in (37, 39) and db_Deferral = 0 then 1 else 0 end) OrderWipCount 
    , sum(case when db_Deferral != 0 then 1 else 0 end) OrderInPendedCount 
相關問題