2016-11-16 69 views
0

我加入了兩個表的多對多關係。如何提高使用NOT IN時的查詢性能

enter image description here 在我的最終結果中,我爲每個PolicyNumber有多個ClassCode。 貌似是:

enter image description here

現在我需要與PaidLosses排除整個PolicyNumber如果在SSRS @ClassCode參數被choosen。 所以,當我用NOT IN來消除PolicyNumber它永遠在旋轉。

select  
      cte1.PolicyNumber, 
      cte1.TransactionEffectiveDate, 
      cc.ClassCode, 
      CASE 
       WHEN ROW_NUMBER() OVER (PARTITION BY cte1.QuoteID, cte1.PolicyNumber, cc.TransactionEffectiveDate ORDER BY (SELECT 0))=1 THEN cte1.WP 
       ELSE 0 
      END as WP--, 
from  cte1 inner join tblClassCodesPlazaCommercial cc on cte1.PolicyNumber=cc.PolicyNumber AND cte1.QuoteID=cc.QuoteID AND cte1.TransactionEffectiveDate=cc.TransactionEffectiveDate 
      AND cc.PolicyNumber IN (SELECT PolicyNumber FROM tblClassCodesPlazaCommercial WHERE ClassCode NOT IN (@ClassCode)) 

是否有其他方法可以提高查詢性能?

整個查詢低於:

DECLARE @ClassCode int = 5151 
;with cte1 
as 
(
SELECT  QuoteID, 
      CONVERT(VARCHAR(10),TransactionEffectiveDate,101) as TransactionEffectiveDate, 
      PolicyNumber, 
      SUM(WrittenPremium) as WP       
FROM  PlazaInsuranceWPDataSet  

WHERE  State IN ('CA','NV','AZ') 
GROUP BY  
      PolicyNumber, 
      QuoteID, 
      TransactionEffectiveDate  
), 
cte3 
as 
(
select  
      cte1.PolicyNumber, 
      cte1.TransactionEffectiveDate, 
      cc.ClassCode, 
      CASE 
       WHEN ROW_NUMBER() OVER (PARTITION BY cte1.QuoteID, cte1.PolicyNumber, cc.TransactionEffectiveDate ORDER BY (SELECT 0))=1 THEN cte1.WP 
       ELSE 0 
      END as WP--, 
from  cte1 inner join tblClassCodesPlazaCommercial cc on cte1.PolicyNumber=cc.PolicyNumber AND cte1.QuoteID=cc.QuoteID AND cte1.TransactionEffectiveDate=cc.TransactionEffectiveDate 
      AND cc.PolicyNumber IN (SELECT PolicyNumber FROM tblClassCodesPlazaCommercial WHERE ClassCode NOT IN (@ClassCode)) 
) 
select 
     c.YearNum, 
     c.MonthNum, 
     SUM(WP) as WP   
from cte3 RIGHT JOIN tblCalendar c ON c.YearNum=YEAR(TransactionEffectiveDate) AND c.MonthNum=MONTH(TransactionEffectiveDate) 
WHERE c.YearNum <>2017 
GROUP BY  
      c.YearNum, 
      c.MonthNum 
ORDER BY c.YearNum desc, 
      c.MonthNum 
+0

很抱歉,但你使用'不IN'而不是'<>'來測試一個整數值:'WHERE ClassCode NOT IN(@ClassCode)'?你有沒有看過'EXISTS'爲你的其他'IN'相關的子查詢?或者一個'外部連接'? – HABO

+0

我也試過<>。仍然,永遠。 – Oleg

+0

也試過EXISTS。還是一樣的 – Oleg

回答

1

對於CTE3,我想你可以寫這樣一來,它可能有助於提高性能

cte3 
as 
(
select  
      cte1.PolicyNumber, 
      cte1.TransactionEffectiveDate, 
      cc.ClassCode, 
      CASE 
       WHEN ROW_NUMBER() OVER (PARTITION BY cte1.QuoteID, cte1.PolicyNumber, cc.TransactionEffectiveDate ORDER BY (SELECT 0))=1 THEN cte1.WP 
       ELSE 0 
      END as WP--, 
from  cte1 
inner join tblClassCodesPlazaCommercial cc 
on cte1.PolicyNumber=cc.PolicyNumber 
    AND cte1.QuoteID=cc.QuoteID 
    AND cte1.TransactionEffectiveDate=cc.TransactionEffectiveDate 

where cc.ClassCode NOT IN (@ClassCode)) 
    ) 
+0

因此,目標是消除不僅僅是ClassCode,而且如果選擇了@ClassCode,也要消除整個PolicyNumber。我已經打了3天,使用'EXISTS','NOT IN','NOT EXISTS',甚至'LEFT ANTI SEMI JOIN'。表演是永恆的。而且你不只是讓我的一天 - 你讓我整整一週!!!!!我無法相信這個簡單的WHERE條款使一切正常,並使它如此之快。 非常感謝! – Oleg

+0

哈哈,我很高興它有幫助。玩的開心 :) –