MySQL在哪里不是非常慢

pix*_*eak 12 mysql sql query-optimization

下面是存储过程中的SQL语句(为简洁而截断):

SELECT * 
FROM item a 
WHERE a.orderId NOT IN (SELECT orderId FROM table_excluded_item);
Run Code Online (Sandbox Code Playgroud)

这个陈述需要30秒左右!但是,如果我删除内部SELECT查询,它将降至1秒.table_excluded_item并不是很大,但我怀疑内部查询的执行速度超过了它的需要.

有更有效的方法吗?

Joh*_*Woo 18

使用 LEFT JOIN

SELECT  a.* 
FROM    item a 
        LEFT JOIN table_excluded_item b
            ON a.orderId = b.orderId
WHERE   b.orderId IS NULL
Run Code Online (Sandbox Code Playgroud)

确保orderId已从两个表中编制索引.


Gor*_*off 5

左连接方法的问题是在生成输出时可能会处理重复记录.有时,事实并非如此...根据这篇文章,left outer join即使在存在重复的情况下,MySQL 也会在对列进行索引时对其进行正确优化.不过,我承认仍然持怀疑态度,这种优化总是会发生.

MySQL有时会出现IN使用子查询优化语句的问题.最好的修复是相关的子查询:

SELECT * 
FROM item a 
WHERE not exists (select 1
                  from table_excluded_item tei
                  where tei.orderid = a.orderid
                  limit 1
                 )
Run Code Online (Sandbox Code Playgroud)

如果你有一个table_excluded_item.orderid的索引,那么这将扫描索引并停在第一个值(这limit 1可能不是绝对必要的).这是在MySQL中实现所需的最快,最安全的方法.

  • 从技术上讲,"限制1"不是必需的; 无论如何,"反加入"将完全相同.(它*可能是*mysql不够聪明,不知道这个) (2认同)