![](/img/trans.png)
[英]query with LEFT JOIN and ORDER BY…LIMIT slow, uses Filesort
[英]Mysql query with join, limit and order is very slow (filesort)
我有以下查詢:
explain select * from users, dls where dls.user_id=users.id and users.status = 'accepted' and users.acc = 0 order by users.user_name desc limit 18416, 16
結果如下:
+----+-------------+-------+------+------------------------+-------------+---------+---------------------------------+-------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+------------------------+-------------+---------+---------------------------------+-------+---------------------------------+
| 1 | SIMPLE | dls | ALL | PRIMARY,user_id | NULL | NULL | NULL | 19910 | Using temporary; Using filesort |
| 1 | SIMPLE | users | ref | PRIMARY,id_user_name | id_user_name | 4 | dls.user_id | 1 | Using where |
+----+-------------+-------+------+------------------------+-------------+---------+---------------------------------+-------+---------------------------------+
2 rows in set (0.00 sec)
這個查詢確實非常緩慢,我無法弄清楚如何解決它。 我閱讀了有關如何通過/限制查詢優化訂單的文章,嘗試了各種索引,但是結果仍然相同。 誰能幫忙嗎?
編輯:模式:
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL auto_increment,
`user_name` varchar(100) character set utf8 NOT NULL,
`status` enum('accepted','rejected') character set utf8 NOT NULL,
`acc` varchar(6) character set utf8 NOT NULL,
PRIMARY KEY (`id`),
KEY `user_name` (`user_name`),
KEY `id_user_name` (`id`,`user_name`)
)
CREATE TABLE `dls` (
`user_id` int(10) unsigned NOT NULL,
`category_id` bigint(20) NOT NULL,
`download_url` varchar(255) character set utf8 NOT NULL,
PRIMARY KEY (`user_id`,`category_id`),
KEY `user_id` (`user_id`)
)
輸出以供Scrummeister查詢;
+----+-------------+-------+------+------------------------+--------+---------+------------------------------+-------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+------------------------+--------+---------+------------------------------+-------+-----------------------------+
| 1 | SIMPLE | u | ALL | PRIMARY,id_user_name | NULL | NULL | NULL | 10838 | Using where; Using filesort |
| 1 | SIMPLE | dls | ref | PRIMARY,user_id | user_id | 4 | u.id | 2 | |
+----+-------------+-------+------+------------------------+--------+---------+------------------------------+-------+-----------------------------+
已知MySql在使用大偏移量的LIMIT
存在問題。
STRAIGHT_JOIN
關鍵字告訴MySql首先掃描users表,然后為每個用戶查找dls
表中的行。
SELECT STRAIGHT_JOIN *
FROM users u JOIN dls ON dls.user_id = users.id
WHERE u.status = 'accepted' and u.acc = 0
ORDER BY users.user_name desc
LIMIT 18416, 16
除非有必要,否則不建議使用STRAIGHT_JOIN,在這種特定情況下,我認為它可能會起作用,因為它可以使用user_name
索引進行排序。
您還有其他選擇:
sort_buffer_size
的大小 read_rnd_buffer_size
的大小(請謹慎!) dls
,僅在users
表上進行分頁,僅應用JOIN
。 WHERE user_name > "{LastPageLastUsername} LIMIT 0,16"
用戶名WHERE user_name > "{LastPageLastUsername} LIMIT 0,16"
則會增加 對於其他優化,請閱讀ORDER BY優化和極限優化
嘗試使用以下幾列向用戶表添加索引
status, acc, user_name
要么
acc, status, user_name
哪個更快
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.