我在MySQL 5.0,5.1,5.5上测试了以下看似简单的查询,发现它非常慢.
select * from entry where session_id in
(select session_id from entry where created_at > [some timestamp])
多个条目可以具有相同的会话ID,但具有不同的created_at时间戳.
该查询旨在获取所有条目,这些条目具有来自同一session_id的至少一个条目,其create_at大于指定的时间戳.
我见过其他人谈到类似查询的MySQL子查询性能问题,并且MySQL认为子查询是一个依赖查询,它正在对外部查询进行全表扫描.建议的解决方法类似于:
select * from entry where session_id in
(select session_id from
(select session_id from entry where created_at > [some timestamp])
as temp)
但是,这个hack对我不起作用,使它更慢.
有关如何重写此查询的任何想法?
最佳答案
根据您的数据分布,使用此选项
SELECT e.*
FROM (
SELECT session_id,MAX(created_at)
FROM entry
GROUP BY
session_id
HAVING MAX(created_at) > $mytimestamp
) ed
JOIN entry e
ON e.session_id = ed.session_id
(在(session_id,created_at))上创建索引,或者:
SELECT DISTINCT e.*
FROM entry ed
JOIN entry e
ON e.session_id = ed.session_id
WHERE ed.created_at > $mytimestamp
(在created_at和session_id上创建两个单独的索引)