一、前言
开发需要定期的删除表里一定时间以前的数据,SQL如下
mysql > delete from testtable WHERE biz_date <= ‘2017-08-21 00:00:00‘ AND status = 2 limit 500\G
前段时间在优化的时候,已经在相应的查询条件上加上了索引
KEY `idx_bizdate_st` (`biz_date`,`status`)
但是实际执行的SQL依然非常慢,为什么呢,我们来一步步分析验证下
二、
表上的字段既然都有索引,那么按照之前的文章分析,是两个字段都可以走上索引的。如果有疑问,请参考文章 10分钟让你明白MySQL是如何利用索引的
既然能够利用索引,表的总大小也就是200M左右,那么为什么形成了慢查呢?
我们查看执行计划,去掉limit 后,发现他选择了走全表扫描。
mysql > desc select * from testtable WHERE biz_date <= ‘2017-08-21 00:00:00‘;
+----+-------------+-----------+------+----------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+----------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | testtable | ALL | idx_bizdate_st | NULL | NULL | NULL | 980626 | Using where |
+----+-------------+-----------+------+----------------+------+---------+------+--------+-------------+
1 row in set (0.00 sec)
-- 只查询biz_date
-- 关键点:rows:980626;type:ALL
mysql > desc select * from testtable WHERE biz_date <= ‘2017-08-21 00:00:00‘ and status = 2;
+----+-------------+-----------+------+----------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+----------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | testtable | ALL | idx_bizdate_st | NULL | NULL | NULL | 980632 | Using where |
+----+-------------+-----------+------+----------------+------+---------+------+--------+-------------+
1 row in set (0.00 sec)
-- 查询biz_date + status
-- 关键点:rows:980632;type:ALL
mysql > desc select * from testtable WHERE biz_date <= ‘2017-08-21 00:00:00‘ and status = 2 limit 100;
+----+-------------+-----------+-------+----------------+----------------+---------+------+--------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len |