从这期开始我会分享几期MySQL 的SQL语句优化的几个案例。
一、SQL语句及执行时间如下
select * from data_test where a=1811190042013;

二、表结构
CREATE TABLE `data_test` (`id` int(11) NOT NULL AUTO_INCREMENT,`a` varchar(20) DEFAULT NULL,`b` bigint(20) DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_a` (`a`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=1570204 DEFAULT CHARSET=utf8;
三、索引详情

注:Cardinality表示索引中唯一值的数目
四、分析
表data_test中a字段有索引,但是查询时间为什么也需要这么久?
首先看执行计划(可以通过Navicat等工具点击“解释”或者在SQL前面加explain查看执行计划)

走不了a字段索引的原因:a字段类型是varchar(20),而输出的参数却是整型。(条件a=1811190042013这个值没加单引号,MySQL认为是整型)
在MySQL中,字符串和数字做比较的话,是将字符串转换成数字再进行比较
也就是SQL相当于
select * from data_test where CAST(a AS signed int)=1811190042013;
由于MySQL对索引字段做函数操作,优化器会放弃走索引(原因是对索引字段做函数操作,可能会破坏索引值的有序性,因此优化器放弃走树索引功能)
五、SQL优化结果
由第三步可知,是因为MySQL发生了隐式转换,导致a字段的查询走不了索引,因此,需要避免隐式转换的情况,改写的SQL如下:
select * from data_test where a=’1811190042013‘;
优化后执行时间

优化后执行计划

加上单引号有效果明显,因此如果碰到有索引的字符串类型字段做条件查询时,记得加上单引号防止隐式转换哦。
参考:林晓斌的“MySQL实战45讲”
本文分享自微信公众号 - MySQL数据库联盟,如有侵权,请联系 service001@enmotech.com 删除。
最后修改时间:2019-12-20 11:33:18
文章转载自MySQL数据库联盟,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




