表索引情况如下:mysql> show index from smw_ids;
+---------+------------+-------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+-------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
| smw_ids | 0 | PRIMARY | 1 | smw_id | A | 1154326 | NULL | NULL | | BTREE | |
| smw_ids | 0 | PRIMARY | 2 | smw_namespace | A | 1154326 | NULL | NULL | | BTREE | |
| smw_ids | 1 | smw_title | 1 | smw_title | A | 1154326 | 50 | NULL | | BTREE | |
| smw_ids | 1 | smw_sortkey | 1 | smw_sortkey | A | 1154326 | 50 | NULL | | BTREE | |
+---------+------------+-------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
4 rows in set (0.05 sec)
mysql> explain partitions SELECT smw_namespace, smw_title FROM `smw_ids` WHERE smw_namespace=1180 ORDER BY smw_sortkey ASC LIMIT 5 ;
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+-----------------------------+
| 1 | SIMPLE | smw_ids | p39 | ALL | NULL | NULL | NULL | NULL | 243654 | Using where; Using filesort |
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+-----------------------------+
1 row in set (0.00 sec)
mysql> 从EXPLAIN结果来看,这个查询是先通过分区得到所有的记录,然后在对这些记录进行排序,排好前5条得到结果集输出。我的理解是在smw_sortkey上面有索引,那么它应该是已经排好序的。在这里为什么不用这个索引呢?
+---------+------------+-------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+-------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
| smw_ids | 0 | PRIMARY | 1 | smw_id | A | 1154326 | NULL | NULL | | BTREE | |
| smw_ids | 0 | PRIMARY | 2 | smw_namespace | A | 1154326 | NULL | NULL | | BTREE | |
| smw_ids | 1 | smw_title | 1 | smw_title | A | 1154326 | 50 | NULL | | BTREE | |
| smw_ids | 1 | smw_sortkey | 1 | smw_sortkey | A | 1154326 | 50 | NULL | | BTREE | |
+---------+------------+-------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
4 rows in set (0.05 sec)
mysql> explain partitions SELECT smw_namespace, smw_title FROM `smw_ids` WHERE smw_namespace=1180 ORDER BY smw_sortkey ASC LIMIT 5 ;
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+-----------------------------+
| 1 | SIMPLE | smw_ids | p39 | ALL | NULL | NULL | NULL | NULL | 243654 | Using where; Using filesort |
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+-----------------------------+
1 row in set (0.00 sec)
mysql> 从EXPLAIN结果来看,这个查询是先通过分区得到所有的记录,然后在对这些记录进行排序,排好前5条得到结果集输出。我的理解是在smw_sortkey上面有索引,那么它应该是已经排好序的。在这里为什么不用这个索引呢?
下面是另外一个表的索引和和EXPLAIN的情况。mysql> explain SELECT smw_namespace, smw_title FROM `smw_ids` WHERE smw_namespace=1180 ORDER BY smw_sortkey ASC LIMIT 5;
+----+-------------+---------+-------+---------------+-------------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+-------------+---------+------+---------+-------------+
| 1 | SIMPLE | smw_ids | index | NULL | smw_sortkey | 257 | NULL | 1144741 | Using where |
+----+-------------+---------+-------+---------------+-------------+---------+------+---------+-------------+
1 row in set (0.00 sec)
mysql> show index from smw_ids;
+---------+------------+-------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+-------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
| smw_ids | 0 | PRIMARY | 1 | smw_id | A | 1259391 | NULL | NULL | | BTREE | |
| smw_ids | 1 | smw_title | 1 | smw_title | A | 629695 | NULL | NULL | | BTREE | |
| smw_ids | 1 | smw_title | 2 | smw_namespace | A | 1259391 | NULL | NULL | | BTREE | |
| smw_ids | 1 | smw_title | 3 | smw_iw | A | 1259391 | NULL | NULL | YES | BTREE | |
| smw_ids | 1 | smw_sortkey | 1 | smw_sortkey | A | 1259391 | NULL | NULL | | BTREE | |
+---------+------------+-------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
5 rows in set (0.00 sec)
不是值多列索引中的最左索引,我没有数据,所以都是全表扫描,但是我force index 一下 如图:
mysql> explain partitions SELECT smw_namespace, smw_title FROM `smw_ids_1` force
index (smw_sortkey) WHERE smw_namespace=1180 ORDER BY smw_sortkey ASC LIMIT 5
-> ;
+----+-------------+-----------+------------+-------+---------------+-----------
--+---------+------+------+-------------+
| id | select_type | table | partitions | type | possible_keys | key
| key_len | ref | rows | Extra |
+----+-------------+-----------+------------+-------+---------------+-----------
--+---------+------+------+-------------+
| 1 | SIMPLE | smw_ids_1 | p39 | index | NULL | smw_sortke
y | 257 | NULL | 141 | Using where |
+----+-------------+-----------+------------+-------+---------------+-----------
--+---------+------+------+-------------+
1 row in set (0.00 sec)
确实如你说的,我另外建了个全字段索引的,不用前缀了。可以用到这个索引咯。mysql> explain SELECT /* TWBrowse::getNaviTermByNs 66.249.71.12 */ smw_namespace, smw_title FROM `smw_ids` WHERE smw_namespace=1180 ORDER BY smw_sortkey DESC LIMIT 1 ;
+----+-------------+---------+-------+---------------+-------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+-------------+---------+------+------+-------------+
| 1 | SIMPLE | smw_ids | index | NULL | idx_smw_ids | 257 | NULL | 1 | Using where |
+----+-------------+---------+-------+---------------+-------------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql>
前缀索引不能对ORDER BY排序起作用,你是哪本书上看到的?《高性能MYSQL》吗?
而你的查询条件是
smw_namespace=1180
ORDER BY smw_sortkey这样smw_namespace=1180条件常规情况下无法利用索引。