那些年使用mysql遇到的查询的坑

一.where 索引列+order by 主键+limit

遇到过好几次这样的sql,select * from 表 where 索引 = xx order by 主键 desc limit 0,20,表里几千万数据,执行时间十几秒。用explain发现sql走的是主键索引,索引文件结果集的量对比时limit所占比例非常小时,才会走order by+limit,官方文档地址:https://dev.mysql.com/doc/refman/8.0/en/limit-optimization.html,解决方案:强制走特定索引。

二.关联子查询

遇到过这样的sql,select * from 表1 where 索引1 in (select 索引 from 表2 where 索引2 = xx),同样表里几千万数据,执行时间几十秒,子查询有五种优化,子查询表上拉(table pullout),重复值消除(duplicate weedout),首次匹配(first match),松散扫描(loose scan),物化。前四种优化策略,子查询都不再是子查询了,会和外层查询组成一个连接(JOIN)查询,只有第 5 种优化策略,子查询还是那个子查询,不同数据量优化方案不一样,至于多表联查,数据量多,坑死没商量,性能差的一笔,被坑过的都知道,解决方案:拆分sql,将逻辑拆分到程序,sql只保留select * from 表1 where 索引1 in xxx

三.数据增多,sql执行计划改变

遇到过一次这种sql,SELECT * FROM 表 WHERE 索引1 IN (xxx) AND 索引2 IN (XX) AND 主键 <= xx ORDER BY 主键 DESC LIMIT 0, 10,表里一亿多数据时,mysql优化器选择使用 index索引,当表里数据大于两亿时,mysql查询优化器选择使用 主键索引,于是悲剧了,查询超慢,总收到慢sql报警,加班加点改了,解决方案:强制走特定索引,在技术群里请教过dba,无法预防,只能等报警。。。

你可能感兴趣的:(mysql,mysql)