TJE*_*TJE 0 mysql sql database greatest-n-per-group
这是一个大约需要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
Run Code Online (Sandbox Code Playgroud)
这是一个查询,它会提取最近有人发送消息的用户列表,以及两者之间的最后一条消息.我怎样才能更改它以便更快?也许没有id IN.也许多个查询?
任何IN查询都可以转换为JOIN.
在这种情况下,您需要转换此查询
SELECT * from TABLE where attr IN (SUBQUERY)
Run Code Online (Sandbox Code Playgroud)
至
SELECT * from TABLE JOIN (SUBQUERY) AS subTable ON (table.attr = subtable.attr)
Run Code Online (Sandbox Code Playgroud)
主要的挑战是不要执行"for循环"类型的子查询(这是你拥有的),因为对于外部查询中的每个元组,都会执行内部查询.如果你有很多元组,结果是你有很多次执行内部查询.
因此,想一想只做一次子查询.例如,在这种情况下,创建一个查询,返回每个消息id,其最大id(仅执行一次),然后加入原始消息表.
换句话说,不要考虑循环.根据您需要加入的集合来思考.
哦,还有一件我刚注意到的事情......如何做一个内部查询(从id限制15的消息顺序中选择id)并将其连接到消息,而不是在整个查询之外使用LIMIT 15.
如果您有外部限制,将在消息中为每个元组评估查询.如果您将LIMIT移到内部,DBMS将在执行复杂查询的其余部分之前计算前15个,它将只执行15次!而不是表中的每个元组.--dmg