这对我来说很奇怪: 一个表'ACTIVITIES',ACTIVITY_DATE有一个索引。具有不同LIMIT值的完全相同的查询会导致不同的执行计划。
这是:
mysql> explain select * from ACTIVITIES order by ACTIVITY_DATE desc limit 20
-> ;
+----+-------------+------------+-------+---------------+-------------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+-------------+---------+------+------+-------+
| 1 | SIMPLE | ACTIVITIES | index | NULL | ACTI_DATE_I | 4 | NULL | 20 | |
+----+-------------+------------+-------+---------------+-------------+---------+------+------+-------+
1 row in set (0.00 sec)
mysql> explain select * from ACTIVITIES order by ACTIVITY_DATE desc limit 150
-> ;
+----+-------------+------------+------+---------------+------+---------+------+-------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+------+---------+------+-------+----------------+
| 1 | SIMPLE | ACTIVITIES | ALL | NULL | NULL | NULL | NULL | 10629 | Using filesort |
+----+-------------+------------+------+---------------+------+---------+------+-------+----------------+
1 row in set (0.00 sec)
为什么我限制150它不使用索引?我的意思是,扫描150行似乎比扫描10629行更快,对吗?
修改
查询使用索引直到“limit 96”并在“limit 97”处启动filesort。 该表没有任何特定内容,即使不是外键,这里是完整的创建表:
mysql> show create table ACTIVITIES\G
*************************** 1. row ***************************
Table: ACTIVITIES
Create Table: CREATE TABLE `ACTIVITIES` (
`ACTIVITY_ID` int(11) NOT NULL AUTO_INCREMENT,
`ACTIVITY_DATE` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`USER_KEY` varchar(50) NOT NULL,
`ITEM_KEY` varchar(50) NOT NULL,
`ACTIVITY_TYPE` varchar(1) NOT NULL,
`EXTRA` varchar(500) DEFAULT NULL,
`IS_VISIBLE` varchar(1) NOT NULL DEFAULT 'Y',
PRIMARY KEY (`ACTIVITY_ID`),
KEY `ACTI_USER_I` (`USER_KEY`,`ACTIVITY_DATE`),
KEY `ACTIVITY_ITEM_I` (`ITEM_KEY`,`ACTIVITY_DATE`),
KEY `ACTI_ITEM_TYPE_I` (`ITEM_KEY`,`ACTIVITY_TYPE`,`ACTIVITY_DATE`),
KEY `ACTI_DATE_I` (`ACTIVITY_DATE`)
) ENGINE=InnoDB AUTO_INCREMENT=10091 DEFAULT CHARSET=utf8 COMMENT='Logs activity'
1 row in set (0.00 sec)
mysql>
我还试图运行“分析表活动”,但这没有改变。
答案 0 :(得分:0)
事情的发展方向。请耐心等一下......
优化器想要使用INDEX,在本例中为ACTI_DATE_I。但如果速度较慢,它不想使用它。
计划A:使用索引。
计划B:忽略表格
在你的情况下(10K的96-1%),它选择了表扫描是令人惊讶的。通常,截止值约为表中行数的10%-30%。
ANALYZE TABLE
应导致重新计算统计信息,可以确信它与其他计划一起使用。
您使用的是哪个版本的MySQL? (不,我不知道这方面有任何变化。)
您可以尝试的一件事:OPTIMIZE TABLE ACTIVITIES;
这将重建表,从而重新打包块并导致潜在不同的统计信息。如果这有帮助,我想知道 - 因为我通常会说"优化表是没用的"。