![](/img/trans.png)
[英]Optimize MySQL query to avoid “Using where; Using temporary; Using filesort”
[英]Optimize table to avoid using temporary and using filesort
我有一个消息表
CREATE TABLE `messages` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`author` int(11) DEFAULT NULL,
`time` int(10) unsigned DEFAULT NULL,
`text` text CHARACTER SET latin1,
`dest` int(11) unsigned DEFAULT NULL,
`type` tinyint(4) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `author` (`author`),
KEY `dest` (`dest`)
) ENGINE=InnoDB AUTO_INCREMENT=2758 DEFAULT CHARSET=utf8;
我需要在两个用户之间收到消息
SELECT
...
FROM
`messages` m
LEFT JOIN `people` p ON m.author = p.id
WHERE
(author = 1 AND dest = 2)
OR (author = 2 AND dest = 1)
ORDER BY
m.id DESC
LIMIT 0, 25
当我解释这个查询时,我得到了
请原谅任何无知,但有没有办法我可以优化这个表,以避免使用临时表和文件输入此查询,现在它不会导致问题,但我很确定将来会很麻烦?
首先,我猜测left join
是没有必要的。 其次,考虑使用union all
。 然后一种方法是:
(SELECT ...
FROM messages m JOIN
people p
ON m.author = p.id
WHERE author = 1 AND dest = 2
ORDER BY id DESC
LIMIT 25
)
UNION ALL
(SELECT ...
FROM messages m JOIN
people p
ON m.author = p.id
WHERE author = 2 AND dest = 1
ORDER BY id DESC
LIMIT 25
)
ORDER BY m.id DESC
LIMIT 0, 25
使用此查询, messages(author, dest, id)
索引messages(author, dest, id)
应该使其快速。 (注意:您可能需要在SELECT
列表中包含m.id
)
以戈登的答案为基础:
SELECT m2..., p...
FROM
(
( SELECT id
FROM messages
WHERE author = 1
AND dest = 2
ORDER BY id DESC
LIMIT 75
)
UNION ALL
(
SELECT id
FROM messages
WHERE author = 2
AND dest = 1
ORDER BY id DESC
LIMIT 75
)
) ORDER BY id DESC
LIMIT 50, 25 ) AS m1
JOIN messages AS m2 ON m2.id = m1.id
JOIN people p ON p.id = m2.author
ORDER BY m1.id DESC
笔记:
people
开始。 LIMIT 75
与LIMIT 50,25
。 OFFSET
分页”有几个问题。 看我的博客 。 TEXT
列,则排序将在RAM中完成。) INDEX(author, dest, id)
, INDEX(author)
变得多余; 算了吧。 ALL
后UNION
不是默认UNION
,但它避免了额外的一个阶段(和临时表),删除重复的数据。 EXPLAIN FORMAT=JSON SELECT ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.