这是一个大约需要5-6秒的查询。内部部分只需要大约50毫秒。
SELECT id,messages.to,messages.from,message,datetime,messages.read
FROM messages WHERE id IN( //inside brackets grabs a list of IDs
SELECT max(messages.id) FROM
(SELECT id,messages.from FROM messages
WHERE messages.to = 'username' AND messages.from != 'username'
UNION
SELECT id,messages.to FROM messages WHERE
messages.from = 'username' AND messages.to != 'username')
AS x
LEFT JOIN messages ON messages.id = x.id
GROUP BY x.from)
ORDER BY id DESC
LIMIT 15它是一个查询,可以提取某人最近发送的用户的列表,也是这两个人之间的最后一条消息。我怎样才能让它变得更快呢?也许没有身份证。也许有多个查询?
发布于 2013-05-02 09:52:59
任何IN查询都可以转换为联接。
在这种情况下,您需要将此查询从
SELECT * from TABLE where attr IN (SUBQUERY)至
SELECT * from TABLE JOIN (SUBQUERY) AS subTable ON (table.attr = subtable.attr)主要的挑战不是执行"for loop“类型的子查询(这就是您所拥有的),因为对于外部查询中的每个元组,都会执行内部查询。如果你有很多元组,结果就是你让innerquery执行了很多次。
因此,请考虑只执行子查询一次。例如,在本例中,执行一个查询,该查询为每个消息id返回其最大id (仅执行一次),然后连接到原始messages表。
换句话说,不要考虑循环。根据你需要加入的集合来思考。
哦,还有一件事我刚注意到...执行内部查询(select id from messages order by id limit 15)并将其连接到消息,而不是将限制15放在整个查询之外,会怎么样呢?
如果您有外部限制,则将针对消息中的每个元组计算查询。如果您将限制移动到内部,DBMS将在执行复杂查询的其余部分之前计算前15个,并且它只会计算15次!而不是针对表中的每个元组。--dmg
https://stackoverflow.com/questions/16329088
复制相似问题