很奇怪,最近发现同事在我的代码里写了一条巨无比臭的慢SQL,执行需要很久,贴一点点SQL,因为私密问题后面还有一堆条件和or就没有贴出来了
SELECT
b.id,
b.change_no,
d.airline,
a.dpt_time,
a.position
FROM
bg_change_order b
LEFT JOIN bg_change_order_ticket c ON b.id = c.id
LEFT JOIN bg_change_order_segment d ON d.change_order_id = b.id
LEFT JOIN bg_order e ON b.ticket_no = e.platform_no
LEFT JOIN bg_order_segment a ON e.id = a.order_id
WHERE
b.change_status = 0
AND c.STATUS IN ( 0, 1 )
AND b.reason = 0
AND b.degree_emergency_in != 1
这条sql其实join的字段都是有索引的,但是就是很奇怪,order表join后并没有踩到索引,导致了all全表扫描,400w+的数据,难怪具慢,但是又很奇怪,所有的join和查询条件都是有索引的,真的是排查了好久,也试过换单值索引,然并卵,还是一样的全表扫描,最后通过baidu查阅资料发现,原来mysql索引匹配不上不止有字段类型
、%like
、不符合最左匹配
、is null | is not null
、!=
、not
、函数操作
、or 两边都不是索引列
等等这些情况不会匹配索引,还有在JOIN
情况下字段或表的字符集、排序规则不匹配
时也不会踩到索引,
字符编码常见的是utf8
和utf8mb4
,utf8mb4
是可以兼容utf8
的,也就是说如果A表是utf8mb4
,B表是utf8
,则on A.uinstanceid = B. uinstanceid
是可以走索引的,但是如果把B表当作主表,让B去join A on B.uinstanceid = A. uinstanceid
则无法走索引
最后贴上救我的老哥原帖地址https://blog.csdn.net/taoshihan/article/details/118065633