mysql explain 当中不靠谱的地方

本文探讨了在特定条件下数据库查询优化器的行为变化,尤其是在涉及大量数据时如何选择索引和进行全表扫描的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1) 扫描的记录数 在10w左右附近的时候,  即使在issuedOn上面加了索引,也会显示有问题,

 select count(*) from table1  where a between '2002-04-22' and '2002-08-12';

+----+-------------+--------------------+-------+---------------+----------+---------+------+--------+-------------+
| id | select_type | table              | type  | possible_keys | key      | key_len | ref  | rows   | Extra       |
+----+-------------+--------------------+-------+---------------+----------+---------+------+--------+-------------+
|  1 | SIMPLE      | table1             | range | a             | a        | 4       | NULL | 169138 | Using where |
+----+-------------+--------------------+-------+---------------+----------+---------+------+--------+-------------+

1 row in set (0.01 sec)

用了key,并且是range


select count(*) from table1  where a between '2002-04-22' and '2002-08-31'; 

+----+-------------+--------------------+------+---------------+------+---------+------+---------+-------------+

| id | select_type | table              | type | possible_keys | key  | key_len | ref  | rows    | Extra       |
+----+-------------+--------------------+------+---------------+------+---------+------+---------+-------------+
|  1 | SIMPLE      | table1             | ALL  | a             | NULL | NULL    | NULL | 1000153 | Using where |
+----+-------------+--------------------+------+---------------+------+---------+------+---------+-------------+
1 row in set (0.00 sec)

居然是全表扫描!!



实际结果是

select count(*) as t1 from table1 where issuedOn between '2002-04-22' and '2002-08-12';
+----------+
| t1       |
+----------+
|    96769 |
+----------+
1 row in set (0.08 sec)


mysql>  select count(*) as t2 from table1 where issuedOn between '2002-04-22' and '2002-08-31';
+----------+
| t2       |
+----------+
|   113185 |
+----------+
1 row in set (0.08 sec)


注意看查询时间,并且在慢查询当中开启了log_queries_not_using_indexes ,没有记录到t2的信息,也就是说依然还是用了索引,把下限改大到 '2002-12-31'; 还是如此,那么根本就没有使用全表扫描嘛!



待续

--------------

后来大概明白了,查询优化器有自己的判断,如

select c1,c2,c3 from t where a = 1 


如果当前的满足条件a=1的条件列很多(我自己测试的结果大概是实际扫描超过过3000条记录,不是看explain 的结果,而是要看explain + force index(a) 的结果,可能和innodb_buffer_pool_size , 还有表本身大小有关,待以后查实),

并且不是只select a 这一列,无论a是不是pk, 那么都有可能不选择a作为索引列,这时候explain,发现居然是全表扫描!!! 可以使用force index(a) 强制查询优化器 使用a做索引,use index(a) 不是强制,只是建议,还是有可能不生效


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值