MYSQL如何使用EXISTS加速请求

时间:2014-01-26 14:45:30

标签: mysql performance optimization query-optimization exists

我有一个SQL请求:

SELECT DISTINCT id_tr 
FROM planning_requests a 
WHERE EXISTS(
        SELECT 1 FROM planning_requests b 
        WHERE a.id_tr = b.id_tr 
        AND trainer IS NOT NULL 
        AND trainer != 'FREE' 
      ) 
AND EXISTS(
        SELECT 1 FROM planning_requests c
        WHERE a.id_tr = c.id_tr 
        AND trainer IS NULL 
    )

但是此请求执行168.9490秒以返回23162行2545088行 我应该使用LEFT JOIN还是NOT IN?我怎样才能重写它

2 个答案:

答案 0 :(得分:0)

您可以通过添加索引来加快速度。我建议:planning_requests(id_tr, trainer)

您可以这样做:

create index planning_requests_id_trainer on planning_requests(id_tr, trainer);

另外,我认为你在第一个子查询中缺少=

编辑:

如果你有很多重复值id_tr,那么除了上面的索引之外,将查询短语为:

select id_tr
from (select distinct id_tr
      from planning_requests
     ) a
where . . .

where条件正在原始表的每一行上运行。 distinct之后处理where

答案 1 :(得分:0)

我认为您的查询可以简化为:

SELECT DISTINCT a.id_tr 
FROM planning_requests a
JOIN planning_requests b
ON b.id_tr = a.id_tr
AND b.trainer IS NULL
WHERE a.trainer < 'FREE'

如果您对planning_requests(培训师)进行索引,那么MySQL可以利用索引范围来获取非FREENULL的所有行。所有数字字符串都符合< 'FREE'条件,并且也不会返回NULL个值。

然后,使用JOIN确保来自该小得多的结果集中的每条记录都有匹配的NULL记录。

对于JOIN,index planning_requests(id_tr,trainer)。

如果您不在FREE1等列中混合类型,可能会更简单。