單表索引order by

create table t6(id int(4) not null,name varchar(10));
Create Table: CREATE TABLE `t6` (
  `id` int(4) NOT NULL,
  `name` varchar(10) DEFAULT NULL,
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
mysql> explain select * from t6 order by id;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | t6    | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

mysql> explain select id from t6 order by id;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t6    | index | NULL          | id   | 4       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

mysql> explain select name from t6 order by id;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | t6    | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
alter table t6 add index(id,name),drop index id;
mysql> explain select * from t6 order by id;
+----+-------------+-------+------+---------------+------+---------+------+--------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows   | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+--------+----------------+
|  1 | SIMPLE      | t6    | ALL  | NULL          | NULL | NULL    | NULL | 131380 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+--------+----------------+
1 row in set (0.00 sec)

mysql> explain select id from t6 order by id;
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | t6    | index | NULL          | id_2 | 17      | NULL | 131380 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
1 row in set (0.00 sec)

mysql> explain select id,name from t6 order by id;
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | t6    | index | NULL          | id_2 | 17      | NULL | 131380 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
1 row in set (0.00 sec)

mysql> explain select glass from t6 order by id;
+----+-------------+-------+------+---------------+------+---------+------+--------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows   | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+--------+----------------+
|  1 | SIMPLE      | t6    | ALL  | NULL          | NULL | NULL    | NULL | 131380 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+--------+----------------+
結論:根據索引字段排序,若是查詢的列中只包含索引字段,那麼mysql引擎會優先選擇從索引中查找這些數據,若是查詢字段中包含
非索引的字段,那mysql引擎就會從整個表中進行掃描,因爲實現order by排序會進行額外的using filesort排序。

alter table t6 add key(id);
mysql> explain select id from t6 order by id;
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | t6    | index | NULL          | id   | 4       | NULL | 131380 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
1 row in set (0.00 sec)
mysql> explain select id,name from t6 order by id;
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | t6    | index | NULL          | id_2 | 17      | NULL | 131380 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
alter table t6 drop id,add primary key(id);
mysql> explain select id,name from t6 order by id;
+----+-------------+-------+-------+---------------+---------+---------+------+--------+-------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows   | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+--------+-------+
|  1 | SIMPLE      | t6    | index | NULL          | PRIMARY | 4       | NULL | 131400 |       |
+----+-------------+-------+-------+---------------+---------+---------+------+--------+-------+
表結構中存在key(id)單列索引和key(id,name)複合索引,若是查詢字段只包含索引字段(普通索引),會優先選擇與字段結構接近
索引。若是是主鍵索引和惟一鍵索引會優先選擇高級索引。

| t6    | CREATE TABLE `t6` (
  `name` varchar(10) DEFAULT NULL,
  `glass` varchar(10) DEFAULT NULL,
  `id` int(4) DEFAULT NULL,
  KEY `name` (`name`,`id`),
  KEY `id` (`id`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
mysql> explain select id,name from t6 ;
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | t6    | index | NULL          | name | 18      | NULL | 131331 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| t6    | CREATE TABLE `t6` (
  `name` varchar(10) DEFAULT NULL,
  `glass` varchar(10) DEFAULT NULL,
  `id` int(4) DEFAULT NULL,
  KEY `id` (`id`,`name`),
  KEY `name` (`name`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
mysql> explain select id,name from t6 order by id;
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | t6    | index | NULL          | id   | 18      | NULL | 131331 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
相同做用的索引,mysql引擎會優先檢索第一個索引,能夠發現若是id索引和name索引調換位置,使用的索引會發生變化,若是加上order by id的話!
mysql> explain select id,name from t6 order by id;
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | t6    | index | NULL          | id   | 18      | NULL | 131331 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
分析:select語句的執行順序,開始->FROM->WHERE->GROUP BY->HAVING->ORDER BY->SELECT->LIMIT->最終結果
緣由是由於order by id 首先選擇了一個與id索引結構接近的索引 ,因爲一條子句只執行一個索引,因此該語句選擇了id索引,同理
mysql> explain select * from t6 where name='' order by id;
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref   | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
|  1 | SIMPLE      | t6    | ref  | name          | name | 13      | const |    1 | Using where |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
該語句中中where語句的優先級高於order by id 因此where優先選擇了一個與name 類似的索引。 mysql


 總結:SQL引擎選擇索引首先根據語句的執行順序,根據語句執行前後順序如where選擇索引,而後再根據優先級進行選擇索引。
sql

相關文章
相關標籤/搜索