问题概述
今天在上班时,DBA突然找出来一段sql,表示该sql存在隐式转换,不走索引。经过我们的查看后,发现是类型varchar的字段, 我们使用条件传入了数值型的值,由于担心违反保密协议,在此就不贴图了,由我重现一下类似情况给大家看一下。
问题重现
首先我们先创建一张用户表test_user,其中USER_ID为了效果我们设置为varchar类型且加上唯一索引。
1
2
3
4
5
6
7
8
9
|
CREATE TABLE test_user ( ID int (11) NOT NULL AUTO_INCREMENT, USER_ID varchar (11) DEFAULT NULL COMMENT '用户账号' , USER_NAME varchar (255) DEFAULT NULL COMMENT '用户名' , AGE int (5) DEFAULT NULL COMMENT '年龄' , COMMENT varchar (255) DEFAULT NULL COMMENT '简介' , PRIMARY KEY (ID) UNIQUE KEY UNIQUE_USER_ID (USER_ID) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
表格数据如下(嘻嘻 数据依旧使用与上次Mysql的文章MySQL使用UNION连接两个查询排序失效相同的数据,但是要注意表结构不同。)
ID | USER_ID | USER_NAME | AGE | COMMENT |
---|---|---|---|---|
1 | 111 | 开心菜鸟 | 18 | 今天很开心 |
2 | 222 | 悲伤菜鸟 | 21 | 今天很悲伤 |
3 | 333 | 认真菜鸟 | 30 | 今天很认真 |
4 | 444 | 高兴菜鸟 | 18 | 今天很高兴 |
5 | 555 | 严肃菜鸟 | 21 | 今天很严肃 |
接下来我们执行以下sql
1
|
EXPLAIN SELECT * FROM test_user WHERE USER_ID = 111; |
发现给出的解释结果如下:
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | test_user | ALL | 5 | Using where |
我们给条件加上引号后再解释以下:
1
|
EXPLAIN SELECT * FROM test_user WHERE USER_ID = '111' ; |
这时候我们发现varchar类型的字段在作为字符串查询的时候使用了索引,在以数值类型进行查询时是不使用索引的。
问题引申
那么问题来了,如果字段是整型的且加上索引,以字符串查询时会不会也不走索引呢?实践出真知,让我们再接着往下测试一下。
1
2
3
4
5
6
7
8
9
10
|
-- 将USER_ID的类型修改为整型 CREATE TABLE test_user ( ID int (11) NOT NULL AUTO_INCREMENT, USER_ID int (11) DEFAULT NULL COMMENT '用户账号' , USER_NAME varchar (255) DEFAULT NULL COMMENT '用户名' , AGE int (5) DEFAULT NULL COMMENT '年龄' , COMMENT varchar (255) DEFAULT NULL COMMENT '简介' , PRIMARY KEY (ID), UNIQUE KEY UNIQUE_USER_ID (USER_ID) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; |
1
|
EXPLAIN SELECT * FROM test_user WHERE USER_ID = 111; |
1
|
EXPLAIN SELECT * FROM test_user WHERE USER_ID = '111' ; |
在执行了上面两个语句后我们发现,int类型的字段无论是以字符串查询还是以数值型查询都会走索引。
结论
- 当我们使用的字段是数值类型时,加引号或者不加引号(sql中单引号和双引号实现相同效果)都不影响索引的使用
- 当我们的字段是字符串类型时,不加引号的查询无法使用索引,加引号的查询才可正常使用索引
综上所述,我认为以后写sql的时候注意最好都加上引号,避免这种字符串类型的不走索引的情况发生,更深层次的原理需要再挖掘一下,如果大家有什么意见可以探讨一下。
到此这篇关于浅谈MySql整型索引和字符串索引失效或隐式转换问题的文章就介绍到这了,更多相关MySql整型索引和字符串索引失效内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/qq_28194001/article/details/90488782