GreatSQL社区

搜索

[已解决] MySQL 5.6中的升序、降序混合排序的理解是否正确

195 1 2024-1-8 10:19
需求

对一张表2个字段排序取50行记录,其中money字段是降序,mid字段是升序。

环境

mysql 5.6

表结构
  1. root@localhost>show create table info;
  2. CREATE TABLE `info` (

  3.   `mid` int(11) unsigned NOT NULL,

  4.   `sitemid` varchar(50) NOT NULL,

  5.   `sid` int(10) unsigned NOT NULL DEFAULT '0' ,

  6.   `exp` int(11) NOT NULL DEFAULT '0' ,

  7.   `money` int(10) NOT NULL DEFAULT '0' ,

  8.   `level` smallint(5) NOT NULL DEFAULT '1',

  9.   `wintimes` int(11) NOT NULL DEFAULT '0',

  10.   `losetimes` int(11) NOT NULL DEFAULT '0',

  11.   `matchstatus` smallint(3) unsigned NOT NULL DEFAULT '0',

  12.   `diamond` int(10) unsigned NOT NULL DEFAULT '0',

  13.   PRIMARY KEY (`mid`),

  14.   KEY `idx_money` (`money`) USING BTREE

  15. ) ENGINE=InnoDB DEFAULT CHARSET=utf8
复制代码
原始SQL
  1. root@localhost> explain SELECT mid,money FROM info ORDER BY money DESC,mid ASC LIMIT 50;                                                
  2. +----+-------------+------+-------+---------------+-----------+---------+------+---------+-----------------------------+
  3. | id | select_type | table| type  | possible_keys | key       | key_len | ref  | rows    | Extra                       |
  4. +----+-------------+------+-------+---------------+-----------+---------+------+---------+-----------------------------+
  5. |  1 | SIMPLE      | info | index | NULL          | idx_money | 4       | NULL | 1348933 | Using index; Using filesort |
  6. +----+-------------+------+-------+---------------+-----------+---------+------+---------+-----------------------------+

  7. root@localhost> SELECT mid,money FROM info ORDER BY money desc,mid ASC LIMIT 50;
  8. +-----------+-----------+
  9. | mid       | money     |
  10. +-----------+-----------+
  11. | 127781800 | 243206203 |
  12. | 159971400 | 212759136 |
  13. ..........略.............
  14. |  11413400 |   7997950 |
  15. | 129845800 |   7897523 |
  16. +-----------+-----------+
  17. 50 rows in set (0.34 sec)
复制代码
子查询
  1. root@localhost> explain select mid,money from (SELECT mid,money FROM info ORDER BY money DESC LIMIT 50) AS t ORDER BY mid  ASC;
  2. +----+-------------+------------+-------+---------------+-----------+---------+------+---------+----------------+
  3. | id | select_type | table      | type  | possible_keys | key       | key_len | ref  | rows    | Extra          |
  4. +----+-------------+------------+-------+---------------+-----------+---------+------+---------+----------------+
  5. |  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL      | NULL    | NULL |      50 | Using filesort |
  6. |  2 | DERIVED     | info       | index | NULL          | idx_money | 4       | NULL | 1348933 | Using index    |
  7. +----+-------------+------------+-------+---------------+-----------+---------+------+---------+----------------+

  8. root@localhost> SELECT * from (SELECT mid,money FROM info ORDER BY money desc LIMIT 50) AS t ORDER BY mid ASC;
  9. +-----------+-----------+
  10. | mid       | money     |
  11. +-----------+-----------+
  12. |    151100 |  11159367 |
  13. |   1406900 |   9697046 |
  14. ..........略.............
  15. | 161220000 |  32384430 |
  16. | 161364600 |  29029832 |
  17. +-----------+-----------+
  18. 50 rows in set (0.00 sec)
复制代码
总结
  • 原始SQL虽然使用了money索引,但是升序排列时对全表所有记录进行了filesort,最终取50行。

  • 子查询SQL首先利用money索引取50行,升序排列时仅仅对50行记录进行filesort,IO操作更少,效率更优。


全部回复(1)
yejr 2024-1-8 12:33:51
是的,这种情况下,改用子查询方式做优化的思路很好
KingHu

1

主题

0

博客

2

贡献

新手上路

Rank: 1

积分
3

合作电话:010-64087828

社区邮箱:greatsql@greatdb.com

社区公众号
社区小助手
QQ群
GMT+8, 2024-5-8 00:54 , Processed in 0.017329 second(s), 13 queries , Redis On.
快速回复 返回顶部 返回列表