mysql order by instr排序的索引优化问题


在mysql中,有表结构如下:


 CREATE TABLE `s_cate` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` char(100) NOT NULL default '',
  `alias` char(20) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8

比如有下面的数据在其中:


 +----+------+-------+
| id | name | alias |
+----+------+-------+
|  1 | xxxx |       | 
|  2 | xxxx |       | 
|  3 | xxxx |       | 
|  4 | xxxx |       | 
|  5 | xxxx |       | 
|  6 | xxxx |       | 
|  7 | xxxx |       | 
|  8 | xxxx |       | 
+----+------+-------+

使用下面的语句查询时,结果如下:


 explain select * from s_cate where id in (3,2,1,6,5,4) order by instr('3,2,1,6,5,4',id);
+----+-------------+--------+------+---------------+------+---------+------+------+-----------------------------+
| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows | Extra                       |
+----+-------------+--------+------+---------------+------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | s_cate | ALL  | PRIMARY       | NULL | NULL    | NULL |    8 | Using where; Using filesort | 
+----+-------------+--------+------+---------------+------+---------+------+------+-----------------------------+

请问如何优化,能让这里不用到filesort呢?

补充一下请教公司dba的回答:

函数返回的结果是动态的,静态索引不起作用

mysql

PengUin 11 years, 2 months ago

首先一个, "请问如何优化,能让这里不用到filesort呢" -- 根据你的表结构和 sql, 这里无解. 因为order by instr('3,2,1,6,5,4',id), order by后面是一个函数, 而mysql里是没有函数索引的, 所以filesort必须有.

其次, 你这里没有用上索引, 也不是因为 WHERE 里有 IN (value_list), 而是你的表记录是在是太少了,全表扫描比走索引效率要高. 我测了一下, 用你的表结构, insert75条记录, 就走索引了. mysql 5.5.24


 mysql> explain select * from s_cate where id in (3,2,1,6,5,4) order by instr('3,2,1,6,5,4',id);
+----+-------------+--------+-------+---------------+---------+---------+------------+-----------------------------+
| id | select_type | table  | type  | possible_keys | key     | key_len | ref  | rows | Extra          |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | s_cate | range | PRIMARY       | PRIMARY | 4       | NULL |    6 | Using where; Using filesort |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)

mysql> select count(*) from s_cate;
+----------+
| count(*) |
+----------+
|       75 |
+----------+
1 row in set (0.03 sec)

压力好大V answered 11 years, 2 months ago

Your Answer