优化NOT IN和子查询?

时间:2013-02-01 16:10:13

标签: mysql optimization

我有这个问题:

select distinct somecolumn from sometable
          where something = somethingelse and
          someid not in (select anotherid from another tabele where ...);

我认为由于subselect,查询运行速度非常慢。有没有办法重写,所以可以删除not in和subselect?

5 个答案:

答案 0 :(得分:3)

使用LEFT JOIN

SELECT  someClumn
FROM    sometable a
        LEFT JOIN anotherTable b
            ON a.someID = b.anotherID 
               -- AND condition for anotherTable
WHERE   a.something = somethingelse AND
        b.anotherID IS NULL

为了获得更好的效果,请在列上定义索引:someIDanotherID

答案 1 :(得分:3)

尝试

select
  distinct somecolumn

from
  sometable t1
  left join anothertable t2 on (t1.someid=t2.otherid and t2.othercondition='else')

where
  t1.something='something else'
  and t2.pk is null
;

并且应该将t2.otherid编入索引。

注意:子查询中的WHERE子句处于JOIN状态。

答案 2 :(得分:3)

理论上,NOT EXISTS应优于NOT IN稍微优化,如果anotherid为NULLable(details on this from a SQL Server standpoint),也应更可靠。虽然我会承认我对MySQL的了解不足以了解这个查询是否会更好:

SELECT somecolumn 
  FROM dbo.sometable AS s
  WHERE something = somethingelse 
  AND NOT EXISTS 
  (
    SELECT 1 FROM dbo.[another table]
    WHERE anotherid = s.someid
  );

但我怀疑这里真正的性能问题是缺少索引,而不是子查询的存在。 sometable.something被编入索引吗? sometable.somied怎么样? [another table].anotherid?此外DISTINCT可能需要额外的排序,但这是否真的有必要?如果你有重复,那可能表明存在设计问题......

答案 3 :(得分:1)

select somecolumn
from sometable
     LEFT JOIN another tabele
        ON someid  = anotherid
          AND (where clause from subquery)
WHERE anotherid IS NULL
    AND something = somethingelse

如果你有一对多的关系,我认为DISTINCT是多余的。

答案 4 :(得分:0)

试试这个

   select  somecolumn from sometable
      where something = somethingelse and
      someid not in (select anotherid from another tabele where ...)
      GROUP BY somecolumn;