【问题标题】:How to improve query performance when using NOT IN使用 NOT IN 时如何提高查询性能
【发布时间】:2017-03-31 06:04:05
【问题描述】:

我正在加入两个表的多对多关系。

在我的最终结果中,每个 PolicyNumber 都有多个 ClassCode。 看起来像这样:

现在,如果选择了 SSRS 中的 @ClassCode 参数,我需要使用 PaidLosses 排除整个 PolicyNumber。 因此,当我使用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

【问题讨论】:

  • 抱歉,您使用NOT IN 而不是&lt;&gt; 来测试单个整数值:WHERE ClassCode NOT IN (@ClassCode)?您是否查看过 EXISTS 的其他 IN 相关子查询?还是OUTER JOIN
  • 我也试过 。仍然,永远。
  • 也试过 EXISTS。还是一样
  • 执行计划是什么样的?您正在执行“NOT IN”的列上是否有索引?

标签: sql-server tsql reporting-services not-exists notin


【解决方案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))
    )

【讨论】:

  • 因此,如果选择了@ClassCode,目标不仅是要消除 ClassCode,还要消除整个 PolicyNumber。我已经用EXISTSNOT INNOT EXISTS 甚至LEFT ANTI SEMI JOIN 与它战斗了 3 天。表演一直持续下去。你不只是让我开心 - 你让我整整一周!!!!!!我不敢相信这个简单的WHERE 子句让一切正常并且变得如此之快。非常感谢!!!!
猜你喜欢
  • 1970-01-01
  • 2014-05-19
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 2012-08-01
  • 2018-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多