啥?我写的一条SQL让公司网站瘫痪了...( 五 )
3 rows in set, 1 warning (0.00 sec)
排查索引没起作用的情况
①模糊查询尽量避免用通配符'%'开头 , 会导致数据库引擎放弃索引进行全表扫描
如下:
SELECT * FROM t WHERE username LIKE '%陈%'
优化方式:尽量在字段后面使用模糊查询 。 如下:
SELECT * FROM t WHERE username LIKE '陈%'
如果需求是要在前面使用模糊查询:
使用 MySQL 内置函数 INSTR(str , substr)来匹配 , 作用类似于 Java 中的 indexOf() , 查询字符串出现的角标位置 。
使用 FullText 全文索引 , 用 match against 检索 。
数据量较大的情况 , 建议引用 ElasticSearch、Solr , 亿级数据量检索速度秒级 。
当表数据量较少(几千条儿那种) , 别整花里胡哨的 , 直接用 like '%xx%' 。
②尽量避免使用 not in , 会导致引擎走全表扫描 。 建议用 not exists 代替
如下:
-- 不走索引
SELECT * FROM t WHERE name not IN ('提莫','队长');
-- 走索引
select * from t as t1 where not exists (select * from t as t2 where name IN ('提莫','队长') and t1.id = t2.id);
③尽量避免使用 or , 会导致数据库引擎放弃索引进行全表扫描
如下:
SELECT * FROM t WHERE id = 1 OR id = 3
优化方式:可以用 union 代替 or 。 如下:
SELECT * FROM t WHERE id = 1
UNION
SELECT * FROM t WHERE id = 3
④尽量避免进行 null 值的判断 , 会导致数据库引擎放弃索引进行全表扫描
如下:
SELECT * FROM t WHERE score IS NULL
优化方式:可以给字段添加默认值 0 , 对 0 值进行判断 。 如下:
SELECT * FROM t WHERE score = 0
⑤尽量避免在 where 条件中等号的左侧进行表达式、函数操作 , 会导致数据库引擎放弃索引进行全表扫描
可以将表达式、函数操作移动到等号右侧 。 如下:
-- 全表扫描
SELECT * FROM T WHERE score/10 = 9
-- 走索引
SELECT * FROM T WHERE score = 10*9
⑥当数据量大时 , 避免使用 where 1=1 的条件 。 通常为了方便拼装查询条件 , 我们会默认使用该条件 , 数据库引擎会放弃索引进行全表扫描
如下:
SELECT username, age, sex FROM T WHERE 1=1
优化方式:用代码拼装 SQL 时进行判断 , 没 where 条件就去掉 where , 有 where 条件就加 and 。
⑦查询条件不能用 <> 或者 !=
使用索引列作为条件进行查询时 , 需要避免使用<>或者!=等判断条件 。
如确实业务需要 , 使用到不等于符号 , 需要在重新评估索引建立 , 避免在此字段上建立索引 , 改由查询条件中其他索引字段代替 。
⑧where 条件仅包含复合索引非前导列
如:复合(联合)索引包含 key_part1 , key_part2 , key_part3 三列 , 但 SQL 语句没有包含索引前置列"key_part1" , 按照 MySQL 联合索引的最左匹配原则 , 不会走联合索引 。
-- 不走索引
select col1 from table where key_part2=1 and key_part3=2
-- 走索引
select col1 from table where key_part1 =1 and key_part2=1 and key_part3=2
⑨隐式类型转换造成不使用索引
如下 SQL 语句由于索引对列类型为 varchar , 但给定的值为数值 , 涉及隐式类型转换 , 造成不能正确走索引 。
select col1 from table where col_varchar=123;
结语
好了 , 通过这篇文章 , 希望你 Get 到了一些分析 MySQL 慢查询的方法和心得 , 如果你觉得这篇文章不错 , 记得分享给朋友或同事 , 让大家少踩点坑 。
作者:陈哈哈
简介:MySQL 社区的非著名贡献者 , 善于白嫖知识;陪伴 MySQL 五年 , 致力于高性能 SQL、事务锁优化方面的研究;长路漫漫 , 希望通过自己的分享让大家少踩一些坑 。 我是陈哈哈 , 一个爱笑的程序员 。
编辑:陶家龙
征稿:有投稿、寻求报道意向技术人请联络 editor@51cto.com
【51CTO原创稿件 , 合作站点转载请注明原文作者和出处为51CTO.com】
- 先别|用了周冬雨的照片,我会成为下一个被告?自媒体创作者先别自乱阵脚
- 当初|这是我的第一部华为手机,当初花6799元买的,现在“一文不值”?
- 发展|我省要求互联网平台坚持依法合规经营 推动线上经济健康规范发展
- 敢动|女生最害怕被“偷看”的3软件,QQ不算啥,第二敢动就“翻脸”
- 页面|流程图怎样画?老板要我帮他做个组织结构图
- 深度|iPhone12到底值得买吗 深度体验一周我发现了这些
- 效果|周冬雨化身美妆效果评测员?相比美妆数码宅的我更期待OPPO新机
- 退费|女子公众号上买菜,出现问题时已充上万元,公司:我们没有退费规矩
- 自助|新型通道-健康码自助核验闸机
- 环境|环境标识认知转盘游戏