if exists子查询的查询优化

时间:2015-09-28 18:32:01

标签: sql sql-server sql-server-2008 query-optimization

我正在尝试优化下面的查询

if exists (select 1 
           from GHUB_DISCREPANCY_REPORT (NOLOCK) 
           where PARTNO = @currentpn and orderID = @oldorderid + 1 
             and (Discr_Fox_Available = 'Y' 
                  or Discr_Fox_NC = 'Y' or Discr_FOC_Available = 'Y' 
                  or Discr_FOC_NC = 'Y' or Discr_Cpa_Available = 'Y' 
                  or Discr_Cpa_NC = 'Y' or Discr_Fox_Tot = 'Y' 
                  or Discr_FOC_Tot = 'Y' or Discr_Cpa_Tot = 'Y'))

我为主键,PartNo,Aging和OrderID列编制了索引。

我可以通过其他方式优化此查询吗?

请建议!

2 个答案:

答案 0 :(得分:0)

首先,尝试GHUB_DISCREPANCY_REPORT(PARTNO, orderId)上的索引。这对您的查询可能有很大帮助。

如果仍然存在性能问题,可以使用一种方法来分离查询,每种查询都可以使用单独的索引进行优化。

if exists (select 1 
           from GHUB_DISCREPANCY_REPORT (NOLOCK) 
           where PARTNO = @currentpn and orderID = @oldorderid and Discr_Fox_Available = 'Y' 
          ) or
    . . .

然后为每个组合分别使用复合索引:GHUB_DISCREPANCY_REPORT(PARTNO, orderId, Discr_Fox_Available)。这是很多索引开销,但可能是值得的。

另一个想法是将所有标志合并为一个:

alter table GHUB_DISCREPANCY_REPORT 
    add Any_Flags as (case when (Discr_Fox_Available = 'Y' 
                  or Discr_Fox_NC = 'Y' or Discr_FOC_Available = 'Y' 
                  or Discr_FOC_NC = 'Y' or Discr_Cpa_Available = 'Y' 
                  or Discr_Cpa_NC = 'Y' or Discr_Fox_Tot = 'Y' 
                  or Discr_FOC_Tot = 'Y' or Discr_Cpa_Tot = 'Y' then 'Y' else 'N' end);

您可以在计算列上添加索引,然后在查询中使用该值:

create index idx_GHUB_DISCREPANCY_REPORT_anyflags on GHUB_DISCREPANCY_REPORT(PARTNO, OrderId, AnyFlags);

if exists (select 1 
           from GHUB_DISCREPANCY_REPORT (NOLOCK) 
           where PARTNO = @currentpn and orderID = @oldorderid and AnyFlags = 'Y' 
          ) 

答案 1 :(得分:0)

“来自tbl_name的top 1 1”在“if exists”(子查询)部分中提供了比“select 1”更好的性能。

请参阅this discussion

在使用“top 1 1”之后,在我的情况下,估计的行数从135765减少到1。