如果存在子查询的查询优化
Query Optimization for if exists sub query
我正在尝试优化下面的查询
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 列。
还有其他方法可以优化此查询吗?
求推荐!
首先,尝试在 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'
)
在 "if exists"(子查询)部分,"top 1 1 from tbl_name" 比“select 1”提供更好的性能。
参考this discussion
在使用 "top 1 1" 后,估计行数从我的 135765 减少到 1。
我正在尝试优化下面的查询
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 列。
还有其他方法可以优化此查询吗?
求推荐!
首先,尝试在 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'
)
"top 1 1 from tbl_name" 比“select 1”提供更好的性能。
参考this discussion
在使用 "top 1 1" 后,估计行数从我的 135765 减少到 1。