浅谈MySql整型索引和字符串索引失效或隐式转换问题
作者:试着奔跑的菜鸟 发布时间:2024-01-15 20:41:39
标签:MySql,整型索引,字符串索引,失效
问题概述
今天在上班时,DBA突然找出来一段sql,表示该sql存在隐式转换,不走索引。经过我们的查看后,发现是类型varchar的字段, 我们使用条件传入了数值型的值,由于担心违反保密协议,在此就不贴图了,由我重现一下类似情况给大家看一下。
问题重现
首先我们先创建一张用户表test_user,其中USER_ID为了效果我们设置为varchar类型且加上唯一索引。
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
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 |
我们给条件加上引号后再解释以下:
EXPLAIN SELECT * FROM test_user WHERE USER_ID = '111';
这时候我们发现varchar类型的字段在作为字符串查询的时候使用了索引,在以数值类型进行查询时是不使用索引的。
问题引申
那么问题来了,如果字段是整型的且加上索引,以字符串查询时会不会也不走索引呢?实践出真知,让我们再接着往下测试一下。
-- 将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;
EXPLAIN SELECT * FROM test_user WHERE USER_ID = 111;
EXPLAIN SELECT * FROM test_user WHERE USER_ID = '111';
在执行了上面两个语句后我们发现,int类型的字段无论是以字符串查询还是以数值型查询都会走索引。
结论
当我们使用的字段是数值类型时,加引号或者不加引号(sql中单引号和双引号实现相同效果)都不影响索引的使用
当我们的字段是字符串类型时,不加引号的查询无法使用索引,加引号的查询才可正常使用索引
综上所述,我认为以后写sql的时候注意最好都加上引号,避免这种字符串类型的不走索引的情况发生,更深层次的原理需要再挖掘一下,如果大家有什么意见可以探讨一下。
来源:https://blog.csdn.net/qq_28194001/article/details/90488782


猜你喜欢
- 操作步骤导入框架,import unitest测试类必须继承类:.class 类名(unittest.TestCase):在类中所有定义te
- props传值时子组件检测不到我们在Vue项目开发的过程中,经常会需要在父子组件传值,我们都知道,父子组件传值的时候是通过 props 来进
- 前言上篇文章主要写了利用scapy实现ping扫描,这篇文章主要是利用scapy模块实现内网ARP扫描实现过程上篇文章中介绍了通过scapy
- 听说pytorch使用比TensorFlow简单,加之pytorch现已支持windows,所以今天装了pytorch玩玩,第一件事还是写了
- 我就废话不多说了,大家还是直接看代码吧~</pre><pre code_snippet_id="1947416&
- 本文实例讲述了Python多进程分块读取超大文件的方法。分享给大家供大家参考,具体如下:读取超大的文本文件,使用多进程分块读取,将每一块单独
- 算法思路1、求取源图I的平均灰度,并记录rows和cols;2、按照一定大小,分为N*M个方块,求出每块的平均值,得到子块的亮度矩阵D;3、
- 当我们的程序报错时,解释器会将整个异常的堆栈信息全部输出出来,举个例子:def foo(): &
- 本文实例为大家分享了JS实现轮播图特效的具体代码,供大家参考,具体内容如下知识点轮播图思想:① 建立一个全局变量索引,始终标记当前显示图片。
- bufio 包介绍 bufio包实现了有缓冲的I/O。它包装一个io.Reader或io.Writer接口对象,创建另一个也实现了
- 备份还原数据库备份数据库企业管理器--或用SQL语句(完全备份):backup database 数据库 to
- 周五上班的主要任务是在公司老平台上用redis处理一个队列问题,顺便复习了一下redis操作的基础知识,回来后就想着在自己的博客demo里,
- 前言:本文的主要内容是介绍Python中 if 语句及其使用,包括条件测试、if -else 语句、if -elif-else 语句以及使用
- Javascript中标签(label)是一个标识符。标签可以与变量重名,它是一个独立的语法元素(既不是变量,也不是类型),其作用是标识”标
- 加了三个验证漏洞以及四个getshell方法# /usr/bin/env python3# -*- coding: utf-8 -*-# @
- 这篇文章主要介绍了python全局变量引用与修改过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 脚本运行环境python 3.6+edge浏览器(推荐使用,因为在edge浏览器中可以获得额外12分,当然chrome浏览器也可以)webd
- 目前两个客户端扩展库连接超时可以设置选项来操作,比如mysqli: <?php //创建对象 $mysqli = mysqli_ini
- 非Data Guard的补丁安装教程可参考《[Oracle] CPU/PSU补丁安装详细教程》,Data Guard需要Primary和St
- 模版结构优化引入模版有时候一些代码是在许多模版中都用到的。如果我们每次都重复的去拷贝代码那肯定不符合项目的规范。一般我们可以把这些重复性的代