我正在寻找一种优化我所拥有的SQL查询的方法。我正在努力获得一定数量的诗歌。
查询如下所示:
SELECT
COUNT(*)
FROM
`poems`
WHERE `id` IN (
SELECT `poem_id`
FROM `poems_genres`
WHERE `genre_title` = 'derision'
)
AND `status` = 'finished';
它需要太长时间(大约6-10秒),因为它不能使用索引(因为我认为IN()?)。有没有办法以不同的方式重写此查询以更快地获得相同的结果?
答案 0 :(得分:11)
in
的MySQL has a problem,它反复重新评估不相关的子查询,就好像它们是相关的一样。重写作为联接会改进吗?
SELECT
COUNT(distinct p.`id`)
FROM `poems` p
JOIN `poems_genres` pg
ON p.`id` = pg.`poem_id`
WHERE pg.`genre_title` = 'derision' AND p.`status` = 'finished';
如果没有,那么根据this article(参见“如何强制内部查询首先执行”部分)将其包装在派生表中可能会有所帮助。
SELECT
COUNT(*)
FROM
`poems`
WHERE `id` IN
(
select `poem_id` from ( SELECT `poem_id`
FROM `poems_genres`
WHERE `genre_title` = 'derision') x
) AND `status` = 'finished';
答案 1 :(得分:1)
您还可以使用EXISTS子句并关联id和poem_id字段
SELECT
COUNT(*)
FROM
`poems` p1
WHERE EXISTS
(
SELECT `poem_id`
FROM `poems_genres` pg
WHERE `genre_title` = 'derision' and p1.id = pg.poem_id
) AND `status` = 'finished';
这与IN的区别在于它会尝试使用索引来代替进行全表扫描。