我有一个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?我怎样才能重写它
答案 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可以利用索引范围来获取非FREE
或NULL
的所有行。所有数字字符串都符合< 'FREE'
条件,并且也不会返回NULL
个值。
然后,使用JOIN
确保来自该小得多的结果集中的每条记录都有匹配的NULL
记录。
对于JOIN
,index planning_requests(id_tr,trainer)。
如果您不在FREE
和1
等列中混合类型,可能会更简单。