为什么索引没有按顺序使用(外键)

时间:2014-10-28 07:24:44

标签: mysql

当我使用带有order by子句的id(主键)时,它使用名为PRIMARY的索引,但是当我使用带有order by子句的countrycode(外键)时,它确实使用了索引。我的输出在下面。

mysql> SHOW CREATE TABLE City;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                         |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

| City  | CREATE TABLE `City` (
|       | `ID` int(11) NOT NULL AUTO_INCREMENT,
|       | `Name` char(35) NOT NULL DEFAULT '',
|       | `CountryCode` char(3) NOT NULL DEFAULT '',
|       | `District` char(20) NOT NULL DEFAULT '',
|       | `Population` int(11) NOT NULL DEFAULT '0',
|       |  PRIMARY KEY (`ID`),
|       |  KEY `CountryCode` (`CountryCode`),
|       |  CONSTRAINT `city_ibfk_1` FOREIGN KEY (`CountryCode`) REFERENCES `Country` (`Code`)
|       |  ) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=latin1 |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+


mysql> EXPLAIN SELECT * FROM City ORDER BY ID;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------+
|  1 | SIMPLE      | City  | index | NULL          | PRIMARY | 4       | NULL | 4321 |       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------+
1 row in set (0.00 sec)

mysql> EXPLAIN SELECT * FROM City ORDER BY COUNTRYCODE;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | City  | ALL  | NULL          | NULL | NULL    | NULL | 4321 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

1 个答案:

答案 0 :(得分:0)

innodb主键中称为"聚簇索引"。

这意味着根据PK值物理排序的行。

因为这些行是自然排序的,所以阅读它们的价格便宜ASCDESC

另一个故事是当你order by另一栏时。

要使用mysql,必须同时读取索引页和数据页,这会大大增加IO。所以mysql决定在内存中对它进行排序(因为根据其启发式内存排序比增加IO更快)。如果你想看到使用该索引进行排序的mysql,你需要:

  1. 将总行数增加到几十万
  2. 仅选择一小部分,例如LIMIT 10
  3. 然后mysql 可能决定使用索引。