mysql索引测试案例(四)

2014-11-24 13:57:21 · 作者: · 浏览: 3
-------+-------------+-------+--------------------+---------+---------+------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+--------------------+---------+---------+------+------+-----------------------------+
| 1 | SIMPLE | user_action | range | PRIMARY,idx_userid | PRIMARY | 4 | NULL | 2 | Using where; Using filesort |
+----+-------------+-------------+-------+--------------------+---------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)
上一个sql排序因为没有使用索引,所以需要排序(Using filesort),而这个是使用了主键,为什么还需要排序,因为需要的顺序和主键的顺序不一样。
说明
mysql的排序有两种:index和filesort,index效率高,它指MySQL扫描索引本身而完成排序。FileSort方式效率较低,因为没有利用索引取到数据,需要mysql通过将取得的数据在内存中进行排序然后再将数据返回给客户。
mysql中filesort 的实现算法实际上是有两种的:
1) 在mysql4.1版本之前只有一种排序算法,首先根据相应的条件取出相应的排序字段和可以直接定位行数据的行指针信息,然后在sort buffer中进行排序,然后再回表取需要
的数据,这里需要二次回表,速度会慢些
2) 从mysql4.1开始,改进了第一种排序算法,一次性取出满足条件行的所有字段,然后在sort buffer中进行排序。目的是为了减少第一次算法中需要二次回表的IO操作,将两
次变成了一次,但相应也会耗用更多的sort buffer空间。
mysql4.1开始以后所有版本同时支持两种算法,mysql主要通过比较我们所设定的 系统参数max_length_for_sort_data 的大小和“select语句所取出的字段类型大小总和”,来判定需要使用哪一种排序算法。如果max_length_for_sort_data 更大,则使用第二种优化后的算法,否则使用第一种算法。如果希望ORDER BY操作的效率尽可能的高,一定要注意max_length_for_sort_data 参数的设置。
mysql> explain select * from user_action where action>
'run' order by action,user_id;
+----+-------------+-------------+-------+---------------------------------------+------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------------------------------+------------+---------+------+------+-------------+
| 1 | SIMPLE | user_action | range | idx_action,idx_useraction_action_name | idx_action | 138 | NULL | 1 | Using where |
+----+-------------+-------------+-------+---------------------------------------+------------+---------+------+------+-------------+
1 row in set (0.00 sec)
这个sql使用了索引的排序,然后回表取数据得到结果集,没有对查询结果排序
mysql> explain select * from user_action where action>'run' order by action,a1;
+----+-------------+-------------+-------+---------------------------------------+------------+---------+------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------------------------------+------------+---------+------+------+-----------------------------+
| 1 | SIMPLE | user_action | range | idx_action,idx_useraction_action_name | idx_action | 138 | NULL | 1 | Using where; Using filesort |
+----+-------------+-------------+-------+---------------------------------------+------------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)
这个sql也使用了索引“idx_action”,为什么就需要对结果集排序呢?因为a1即不再索引idx_action里,也不是主键;所以需要对结果集排序,要使用filesort,可以通过增大max_length_for_sort_data来优化filesort。或者就避免filesort
mys