MySQL子查询真的很慢...解决方法?
我已经在MySQL 5.0,5.1,5.5上测试了以下看似简单的查询,发现它非常慢。MySQL子查询真的很慢...解决方法?
select * from entry where session_id in
(select session_id from entry where created_at > [some timestamp])
多个条目可以具有相同的会话ID,但具有不同的created_at时间戳。 该查询旨在获取所有条目的来自同一个session_id,其created_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)
但是,这种黑客不适合我,并使其更慢。
有关如何重写此查询的任何想法?
根据您的数据分发,使用此
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
)
如何:
SELECT DISTINCT e2.*
FROM entry e1
INNER JOIN entry e2
ON e1.session_id = e2.session_id
WHERE e1.created_at > [some timestamp]
如果您还没有他们,就created_at
和session_id
指标很可能是有帮助。
你还需要'group by e2.id',否则你会得到重复的。 – 2011-05-13 22:02:07
谢谢。实际上,这是我最初尝试的。这是给我重复。对我来说没有发生过使用分组。或者你可以使用不同的e2。*。 – n00b 2011-05-13 22:05:07
新增更正。 – 2011-05-13 23:02:38
我也有一个双子查询技巧的问题, btw我刚刚发现,使用这个工作对我来说(根据您的查询):
select * from entry where session_id in
(select (select session_id from entry where created_at > [some timestamp]))
在我的情况下,原有的查询可以使用一个连接或“正常”双子查询招小时,与修改后的双子查询用了0秒工作: )
这是非常有用的,因为很容易申请!然而奇怪的是MySQL的这种行为...... – Pisu 2011-10-03 16:32:55
只有在内部查询返回单个结果的情况下,这才起作用。否则,你会得到错误“子查询返回多于一行” – ecdeveloper 2015-10-26 23:19:43
你达人。谢谢! 我从第二个查询开始,但忽略了不同。我不知道你可以使用通配符将不同的结果应用于整个结果集。真棒。 – n00b 2011-05-13 22:05:28