- 论坛徽章:
- 0
|
希望大家指点
表结构如下所示:
mysql> show create table book\G
*************************** 1. row ***************************
Table: book
Create Table: CREATE TABLE `book` (
`book_id` int(11) NOT NULL AUTO_INCREMENT,
`status` int(11) NOT NULL,
`level` int(11) NOT NULL,
`update_time` datetime DEFAULT NULL,
...... snip .......
PRIMARY KEY (`book_id`),
KEY `S_L_U` (`status`,`level`,`update_time`),
KEY `S_U` (`status`,`update_time`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
status 有6个取值,level只有2个取值。该表总共有72550行数据,status=2的有28527行数据,level=0的有72330行数据,level=1的有220行数据。
我有个Query是这样的:
select update_time from book where status = 2 order by update_time
desc limit offset,row_count
按照原理,该Query应该是使用S_U索引的。
当offset比较小的时候,该Query使用S_U(status,update_time)索引。
mysql> explain select update_time from book where status = 2 order
by update_time desc limit 100,50\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: book
type: range
possible_keys: S_L_U,S_U
key: S_U
key_len: 4
ref: NULL
rows: 27893
Extra: Using where; Using index
1 row in set (0.00 sec)
但是随着offset的增大,该Query会选择使用S_L_U(status,level,update_time)索引。而且从explain的输出来看,Extra列显示还有using
index,但是我strace了这个sql的过程,发现该Query进行了50次的表数据读取,这个是第一个不理解的地方,还有为啥不选择S_U索引,S_U索引能够覆盖update_time,不是连排序都省了吗??
mysql> explain select update_time from book where status = 2 order
by update_time desc limit 28000,50\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: book
type: ref
possible_keys: S_L_U,S_U
key: S_L_U
key_len: 4
ref: const
rows: 19199
Extra: Using where; Using index; Using filesort
1 row in set (0.00 sec)
mysql> select update_time from book where status = 2 order by
update_time desc limit 28000,50;
+---------------------+
| update_time |
+---------------------+
| 2008-08-11 17:08:17 |
...... snip ......
| 2008-08-11 14:00:39 |
+---------------------+
50 rows in set (0.03 sec)
如果使用force index 执行使用S_U索引的话,反而没有使用S_L_U索引速度快,这个是为啥呢?
mysql> explain select update_time from book force index(S_U) where
status = 2 order by update_time desc limit 28000,50\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: book
type: ref
possible_keys: S_U
key: S_U
key_len: 4
ref: const
rows: 27893
Extra: Using where; Using index
1 row in set (0.00 sec)
mysql> select update_time from book force index(S_U) where status = 2
order by update_time desc limit 28000,50;
+---------------------+
| update_time |
+---------------------+
| 2008-08-11 17:08:17 |
...... snip ......
| 2008-08-11 14:00:39 |
+---------------------+
50 rows in set (0.10 sec)
|
|