相关免费学习推荐:mysql视频教程
背景
在一次进行SQL查询时,我试着对where条件中vachar类型的字段去掉单引号查询,这个时候发现这条本应该很快的语句竟然很慢。这个varchar字段有一个复合索引。其中的总条数有58989,甚至不加单引号查出来的数据不是我们想要的数据。使用的是MysqL 5.6版本,innoDB引擎 实际情况如下下面我们来看一下执行的结果
在上面的描述中我们还得注意就是,你的where条件的字符串不加单引号必须是全数字。不然就会报错
还有可能查出来的数据不是我们想要的数据。如下图
分析
从执行结果来看,使用了单引号的走了对应的索引。没有使用单引号的没有走索引,进行了全表扫描。为什么会这样呢? MysqL的优化器怎么不直接进行类型转换呢?@H_403_45@在SQL语句中单引号的引入也就是代表这个类型是字符串数据类型CHAR, VARCHAR, BINARY, VARBINARY, BLOB, TEXT, ENUM,和 SET。。不加单引号也就代表这是一个字符串之外的类型,如int,bigDecimal类型等如果给一串有字幕和特殊符号的字符串不加单引号,后果就是类型转换失败导致sql不能执行。如上图所述:
1054 - UnkNown column '000w1993521' in 'where clause', Time: 0.008000s
我们先来看一下一条sql的执行过程
(网图)
我们先得出结论:如果对索引字段做函数 *** 作(本例是cast函数做了隐式的转换),可能会破坏索引值的有序性,因此优化器就决定放弃走树搜索功能。(https://dev.MysqL.com/doc/refman/5.7/en/cast-functions.HTML)[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l5AwT0xu-1607244327891)(http://note.youdao.com/yws/res/23689/CE6F785994E6476D816B23787CE65217)]意思也就是:请注意,如果您使用BINARY,CAST()或CONVERT()转换索引列,则MysqL可能无法有效使用索引。查出来的数据不准确,也是因为隐式转换,转换后导致数值类型不一样,导致不等变为相等。隐式转换
1. 产生条件
当 *** 作符与不同类型的 *** 作数一起使用时,会发生类型转换以使 *** 作数兼容。则会发生转换隐式
发生隐式转换的条件:
2. 分析实际遇到的情况
1.那我们也就清楚了,上面我提出的例子是整数和字符串的比较,那就属于其他情况了。那我们就先来分析一下索引失效的原因
由于属于隐式转换的其他情况,所以对比值都得转换为浮点数进行比较我们先将查询条件值进行转换为浮点数,再着将表的记录值也得进行转换,所以这个时候此前已经创建好的索引排序已经不能生效了。因为隐式转换(函数)已经改变了原来的值,所以说优化器在这里就直接不选用索引,直接使用全表扫描。2.查询出不匹配的值(或者说是部分匹配的值),如上面的查询结果。这真得看看源码了,这也就是MysqL的隐式转换规则。这里不就细分析了(因为没有查到相关的文档)
由于历史原因,需要兼容旧的设计,可以使用 MysqL 的类型转换函数 cast 和 convert,来明确的进行转换。
总结
总结想了解更多编程学习,敬请关注php培训栏目!
以上是内存溢出为你收集整理的解决Mysql 5.6 "隐式转换"导致的索引失效和数据不准确的问题全部内容,希望文章能够帮你解决解决Mysql 5.6 "隐式转换"导致的索引失效和数据不准确的问题所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)