Mysql中where条件一个单引号引发的性能损耗
日常写SQL中可能会有一些小细节忽略了导致整个sql的性能下降了好几倍甚至几十倍,几百倍。以下这个示例就是mysql语句中的一个单引号('')引发的性能耗损,我相信很多朋友都遇到过,甚至还在这样写。
先看下我的表结构:
CREATE TABLE `d_sku` (
`id` varchar() NOT NULL,
`commodity_id` varchar() DEFAULT NULL,
`counts` int() DEFAULT NULL,
`price` double(,) DEFAULT NULL,
`status` int() DEFAULT NULL,
`location` varchar() DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`create_id` varchar() DEFAULT NULL,
`modify_time` datetime DEFAULT NULL,
`provalue_str` varchar() DEFAULT NULL,
`category_id` varchar() DEFAULT NULL,
`customer_id` varchar() DEFAULT NULL,
`cert_no` varchar() DEFAULT NULL,
`profit` double DEFAULT NULL,
`check_cargo` int() DEFAULT '',
`check_time` datetime DEFAULT NULL,
`keep_last_checked` int() DEFAULT NULL,
`approval_status` int() DEFAULT '',
`code` varchar() DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_price` (`price`) USING BTREE,
KEY `index_category_status` (`category_id`,`status`) USING BTREE,
KEY `index_modifytime` (`modify_time`) USING BTREE,
KEY `index_customerId_categoryId` (`customer_id`,`category_id`) USING BTREE,
KEY `index_certNo_customerId` (`cert_no`,`customer_id`) USING BTREE,
KEY `index_provaluestr` (`provalue_str`()) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
一个电商平台的SKU数据库表结构模式,该表中数据条数376138。以此下两种查询方式看下执行效率。查询语句都是从该表中查询一条数据分类为d2a17030-149d-11e5-a9de-000c29d7a3a0并且编号为5186354366的数据。
1.实例测试
1.对查询内容添加单引号
SELECT * FROM d_sku d where category_id='d2a17030-149d-11e5-a9de-000c29d7a3a0' and d.cert_no='';
【消息】:执行成功,当前返回:[1]行,耗时:[1ms.]。查询速度非常快。
2.对查询内容不添加单引号
SELECT * FROM d_sku d where category_id='d2a17030-149d-11e5-a9de-000c29d7a3a0' and d.cert_no=;
【消息】:执行成功,当前返回:[1]行,耗时:[1210ms.]发现两者之间的执行效率显而易见啊。
2.两者区别分析
这样一查询效果真的是显而易见,添加单引号查询才1ms,不添加单引号查询的耗时是1210ms.一条数据就这么明显了。可想而知这种性能损失有多大。但是为什么会这样呢?先从分析索引看起。使用关键词 “explain” 查看sql执行效率详细(关键词使用介绍点传送门)。
explain SELECT * FROM d_sku d where category_id='d2a17030-149d-11e5-a9de-000c29d7a3a0' and d.cert_no=''; explain SELECT * FROM d_sku d where category_id='d2a17030-149d-11e5-a9de-000c29d7a3a0' and d.cert_no=;
图一:添加单引号
图二:未添加单引号
两条数据对比分析:
图一:
添加单引号后的性能详情,其中表头key这里显示出来真正使用了组合索引“index_certNo_customerId” ,其中这两个索引对应的列正好是“category_id”和“cert_no”。再看rows这,表示查询这条数据只检索了一条数据,因为是这里索引生效了,所以通过“cert_no”编号直接查询到了数据。
图二:
未添加单引号后的性能详情,发现真正使用的索引只有“index_category_status”,回到创建表结构的时候可以发现这条索引信息是添加`category_id`,`status`这两个列的,表示只用到了category_id,而第二个条件的cert_no列并没有用到索引,所以性能的损耗就在这里发生了。
总结:
原因就是因为我们创建表结构的时候cert_no字段是varchar类型的,而where时未添加单引号的时候参数是被做为数字类型来使用的,那不同的类型做查询的时候肯定是要转型的,数据类型转换的话就无法正常使用索引了。所以可以得到一个结论就是Int类型的数据在转换varchar再使用是不会使用索引的。我们可以修改表结构将cert_no改为int类型后在使用不添加单引号的参数查询时性能也就是正常的了。同样也是可以通过添加单引号来实现。
Mysql中where条件一个单引号引发的性能损耗的更多相关文章
- sql中 查询条件出现单引号和特殊字符处理
1.两个单引号转为一个单引号 example: select * from tb where name=' '' ' 2.如果出现 "_","%" 需要用 ...
- Mysql中反引号和单引号的区别
反引号,一般在ESC键的下方. 它是为了区分MYSQL的保留字与普通字符而引入的符号.举个例子:SELECT `select` FROM `test` WHERE select='字段值'在test表 ...
- MyBatis中的条件判断单引号双引号的使用
对于字符串判断, <if test="aIn != 'A'" >会出现问题,系统会试图把'A'转成数字,改为 <if test='aIn != "A&q ...
- Mysql中的条件语句if、case
Mysql中的条件语句在我们对数据进行转换的时候比较有用,这样就不需要创建中转表. IF 函数 IF(expr1,expr2,expr3) 如果 expr1 是TRUE (expr1 <> ...
- json.loads()的字符串中为单引号引发的错误
如下错误属于弱智错误,但是错的原因让我无语,所以记录一下 str2="{'card':6217001650004184441}"print(json.loads(str2)) Tr ...
- 【python】sql语句插入中内容同时包含单引号和双引号的解决办法
在python中调用MySQLdb模块插入数据信息,假设待输入信息data为: Hello'World"! 其中同时包含了单引号和双引号 一般插入语句为 sql = "insert ...
- mysql 字段引号那个像单引号的撇号用法
我们知道通常的SQL查询语句是这么写的: select col from table; 这当然没问题,但如果字段名是“from”呢? select from from table; 若真的这么写,必然 ...
- Excel公式中双引号和单引号输入和显示以及函数的选择确认
[Excel中显示双引号] 1.直接输入双引号“”或单引号“ 2.工式中显示双引号需输入“”“”“”(六个引号)或单引号需输入“”“”(四个引号) [Excel中快速确认已选择的函数] 1.用键盘的上 ...
- 菜菜小问题——python中print函数 以及单引号、双引号、三引号
直接面对——引号,就是为了保证打印出来的东东符合预期 如:print("小菜菜") 结果是: .================1========================= ...
随机推荐
- 新概念英语(1-99)Ow!
Lesson 99 Owl! 啊哟! Listen to the tape then answer this question. Must Andy go to see the doctor?听录音, ...
- hadoop2.7.3+spark2.1.0+scala2.12.1环境搭建(4)SPARK 安装
hadoop2.7.3+spark2.1.0+scala2.12.1环境搭建(4)SPARK 安装 一.依赖文件安装 1.1 JDK 参见博文:http://www.cnblogs.com/liugh ...
- python实现 字符串匹配函数
通配符是 shell 命令中的重要功能,? 表示匹配任意 1 个字符,*表示匹配 0 个或多个字符.请使用你熟悉的编程语言实现一个字符串匹配函数,支持 ? 和 * 通配符.如 "a?cd*d ...
- python网络编程基础(一)
一.C/S架构 客户端/服务端架构 二.OSI七层架构 七层模型,亦称OSI(Open System Interconnection)参考模型,是参考模型是国际标准化组织(ISO)制定的一个用于计算机 ...
- Python系列-python内置函数
abs(x) 返回数字的绝对值,参数可以是整数.也可以是浮点数.如果是复数,则返回它的大小 all(iterable) 对参数中的所有元素进行迭代,如果所有的元素都是True,则返回True,函数等价 ...
- vuex commit保存数据技巧
vuex 单向数据流,推荐的commit 改变state数据,写起来非常繁琐,因为改数据可能要写很多commit函数. 依据我的理解,单向数据流主要是为了避免数据混乱,便于调试. 说白了,就是一个数据 ...
- scrapy中的request
scrapy中的request 初始化参数 class scrapy.http.Request( url [ , callback, method='GET', headers, body, cook ...
- 基于angularJS搭建的管理系统
前言 angularJS搭建的系统,是一年前用的技术栈,有些地方比较过时,这里只是介绍实现思路 前端架构 工程目录 项目浅析 项目依赖包配置package.json { "name" ...
- java代码优化细节
在代码线上运行的过程中,往往会出现很多我们意想不到的错误,不少错误定位到最后往往是一个非常小的原因导致的.然而因为线上环境和开发环境是非常不同的,为了解决一个错误,我们需要先查找错误原因.修改验证.打 ...
- [LeetCode] Couples Holding Hands 两两握手
N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum numb ...