mysql的索引不工作

路飞 发布于 2015/12/18 11:07
阅读 278
收藏 0

最近统计信息时遇到的一个奇怪现象,同一个sql语句,测试环境执行能使用索引,线上环境不使用索引

sql如下

SELECT t_order.`tb_order_no` FROM `payment_tmall_order_2015` AS t_order
WHERE t_order.create_time > '2015-11-11 00:00:00'
AND t_order.`order_status_tmall` = 'SUCCESS'
AND NOT EXISTS (
	SELECT * 
	FROM `payment_dprp_point_2015` AS dprp 
	WHERE t_order.`tb_order_no` = dprp.`order_no`
)



其中t_order.create_time, t_order.tb_order_no, dprp.order_no都是有索引的

测试环境的explain

线上环境的explain

可以看到查询t_order的时候,测试环境使用的type=range的索引,线上环境直接全表扫描了,线上环境执行一下要2.xx秒的时间

大家有遇到过这种情况么


福利送上

加载中
0
路飞
路飞

唔,原因找到了


create_time > '2015-11-11 00:00:00'



线上的库里11-11之后的订单数占订单表总数的2/3,mysql认为扫全表要比使用索引更好,测试环境因为数据比较少,所以没有这种情况。


参考:

Each table index is queried, and the best index is used unless the optimizer believes that it is more efficient to use a table scan. At one time, a scan was used based on whether the best index spanned more than 30% of the table, but a fixed percentage no longer determines the choice between using an index or a scan. The optimizer now is more complex and bases its estimate on additional factors such as table size, number of rows, and I/O block size.

http://dev.mysql.com/doc/refman/5.7/en/where-optimizations.html

所以说,表结构和业务功能一定要前期好好设计,减少逻辑缺陷,这个sql就是因为现有业务的一个小漏洞,导致部分订单有问题,必须统计出来进行修复,还好只需要执行一次,慢点就慢点吧。。。

0
Tuesday
Tuesday

t_order.create_time >'2015-11-11 00:00:00'

这写法, 政治老师死得早.. 

路飞
路飞
肿么了这写法
0
Java_Coder
Java_Coder

1.线上,线下explain一下

2.再次确认线上,线下索引(show index),sql是否一样,MySQL版本,设置等信息

0
爱好者新手
使用force index可以解决这个问题

魔力猫
魔力猫
不分析直接强制索引,死得更快。
0
宏哥
宏哥
转 postgresql
聽雨人
聽雨人
当预估数据量大于表数据的某个比时,不走索引,这个做法pg不是这样吗?
0
mark35
mark35
早转pgsql,否则以后会有无数的坑等着你踩
返回顶部
顶部