在(子查询)或(列表)性能问题的位置

时间:2016-08-31 10:30:11

标签: sql sql-server

我想根据原始表中的字段是否在两个列表中来制作列表。因此我的代码是:

SELECT *
FROM ListofPlaces
WHERE Property = 'MODERATE'
    and (HOMELAND in (
        SELECT distinct HOMELAND
        FROM PLANS
        WHERE left(plans.code, 1) = '1') 
    or HOMELAND in (
        'PlaceA'
        , 'PlaceB'
        , 'PlaceC'
        , 'PlaceD'
        , 'PlaceE'))

列表和子查询将单独运行,对于子查询采用00:00:01.43,对于列表采用00:00:00.13,但是一旦合并,它们需要大约一分钟。

我尝试过使用左连接,但这会导致性能降低更多。

表' PLANS'是一个4M +行的较大表,而地点列表小于1000。

我的问题是我是否有效地使用和/或运算符,如果有,是否有更有效的方法来运行此查询?

2 个答案:

答案 0 :(得分:2)

尝试使用UNION

重写此内容
SELECT *
FROM ListofPlaces
WHERE Property = 'MODERATE' AND
      HOMELAND IN (SELECT HOMELAND
                   FROM PLANS
                   WHERE left(plans.code, 1) = '1'
                  ) 
UNION
SELECT *
FROM ListofPlaces
WHERE Property = 'MODERATE' AND
      HOMELAND in ('PlaceA', 'PlaceB', 'PlaceC', 'PlaceD', 'PlaceE');

优化器有时会被OR混淆。如果两个列表包含类似的元素,则此处可能需要UNION而不是UNION ALL。否则,如果您知道它们是不相交的,请使用UNION ALL

答案 1 :(得分:1)

为什么不加入?

SELECT LoP.*
FROM ListofPlaces LoP
left join PLANS Pl
  on LoP.HOMELAND = Pl.HOMELAND
WHERE Property = 'MODERATE'
    and (left(plans.code, 1) = '1' 
    or LoP.HOMELAND in (
        'PlaceA'
        , 'PlaceB'
        , 'PlaceC'
        , 'PlaceD'
        , 'PlaceE'))