也议MySQL中隐式转换
1. 环境说明
blog地址:http://blog.csdn.NET/hw_libo/article/details/39252427
RHEL 6.4 x86_64 + MySQL 5.6.19
测试表:
- MySQL [test]> show create table emp\G
- *************************** 1. row ***************************
- Table: emp
- Create Table: CREATE TABLE `emp` (
- `EMPNO` int(11) NOT NULL,
- `ENAME` varchar(15) NOT NULL,
- `JOB` varchar(15) NOT NULL,
- `MGR` int(11) DEFAULT '0',
- `HIREDATE` timestamp NULL DEFAULT NULL,
- `SAL` int(20) DEFAULT '0',
- `COMM` int(11) DEFAULT '0',
- `DEPTNO` int(11) NOT NULL,
- PRIMARY KEY (`EMPNO`),
- KEY `idx_deptno` (`DEPTNO`),
- KEY `idx_sal` (`SAL`),
- KEY `idx_comm` (`COMM`),
- KEY `idx_ename` (`ENAME`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8
- 1 row in set (0.00 sec)
- </pre><pre name="code" class="sql">MySQL [test]> select * from emp;
- +-------+--------+-----------+------+---------------------+------+------+--------+
- | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
- +-------+--------+-----------+------+---------------------+------+------+--------+
- | 7369 | SMITH | CLERK | 7902 | 1980-12-17 00:00:00 | 800 | NULL | 20 |
- | 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 00:00:00 | 1600 | 300 | 30 |
- | 7521 | WARD | SALESMAN | 7698 | 1981-02-22 00:00:00 | 1250 | 500 | 30 |
- | 7566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975 | 0 | 20 |
- | 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 00:00:00 | 1250 | 1400 | 30 |
- | 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 00:00:00 | 2850 | 0 | 30 |
- | 7782 | CLARK | MANAGER | 7839 | 1981-06-09 00:00:00 | 2450 | 0 | 10 |
- | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 00:00:00 | 3000 | NULL | 20 |
- | 7839 | KING | PRESIDENT | 0 | 1981-11-17 00:00:00 | 5000 | 0 | 10 |
- | 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 00:00:00 | 1500 | 0 | 30 |
- | 7876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100 | 0 | 20 |
- | 7900 | JAMES | CLERK | 7698 | 1981-12-03 00:00:00 | 950 | 0 | 30 |
- | 7902 | FORD | ANALYST | 7566 | 1981-12-03 00:00:00 | 3000 | 0 | 20 |
- | 7934 | MILLER | CLERK | 7782 | 1982-01-23 00:00:00 | 1300 | 0 | 10 |
- | 7936 | 23456 | BOSCO-DBA | 7788 | 2014-09-13 16:13:56 | 2450 | 800 | 10 |
- +-------+--------+-----------+------+---------------------+------+------+--------+
- 15 rows in set (0.00 sec)
2. 数值类型(int)
首先提个问题,如上测试表emp中empno是主键,类型为int,那么:
- select * from emp where empno='7788';
会产生隐式转换吗?
下面实验证明:
- MySQL [test]> select * from emp where empno=7788;
- +-------+-------+---------+------+---------------------+------+------+--------+
- | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
- +-------+-------+---------+------+---------------------+------+------+--------+
- | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 00:00:00 | 3000 | NULL | 20 |
- +-------+-------+---------+------+---------------------+------+------+--------+
- 1 row in set (0.00 sec)
- MySQL [test]> explain select * from emp where empno=7788;
- +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
- | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
- +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
- | 1 | SIMPLE | emp | const | PRIMARY | PRIMARY | 4 | const | 1 | NULL |
- +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
- 1 row in set (0.00 sec)
- MySQL [test]> select * from emp where empno='7788';
- +-------+-------+---------+------+---------------------+------+------+--------+
- | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
- +-------+-------+---------+------+---------------------+------+------+--------+
- | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 00:00:00 | 3000 | NULL | 20 |
- +-------+-------+---------+------+---------------------+------+------+--------+
- 1 row in set (0.00 sec)
- MySQL [test]> explain select * from emp where empno='7788';
- +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
- | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
- +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
- | 1 | SIMPLE | emp | const | PRIMARY | PRIMARY | 4 | const | 1 | NULL |
- +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
- 1 row in set (0.00 sec)
可见,针对数据类型字段,即使类型不一致,并不影响是否使用索引,执行计划是一样的,不会产生隐式转换。但仍然建议在生产库中尽量避免出现这样的SQL。
注意:
数值类型有一种隐式转换,如果以数字开关的,后面的字符将被截断,只取前面的数字值,如果不以数字开关的将被置为0。如下:
- MySQL [test]> select * from emp where empno='7788ab12'; ## 这个就相当于empno=7788,后面的ab12将被截断,并且不影响索引的使用
- +-------+-------+---------+------+---------------------+------+------+--------+
- | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
- +-------+-------+---------+------+---------------------+------+------+--------+
- | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 00:00:00 | 3000 | NULL | 20 |
- +-------+-------+---------+------+---------------------+------+------+--------+
- 1 row in set, 1 warning (0.00 sec)
- MySQL [test]> show warnings;
- +---------+------+----------------------------------------------+
- | Level | Code | Message |
- +---------+------+----------------------------------------------+
- | Warning | 1292 | Truncated incorrect DOUBLE value: '7788ab12' |
- +---------+------+----------------------------------------------+
- 1 row in set (0.00 sec)
- MySQL [test]> select * from emp where empno='ab7788'; ## 这个就相当于empno=0
- Empty set (0.01 sec)
3. 字符类型(varchar)
同样,针对测试表emp中的ename字段(varchar类型),上面有一辅助索引idx_ename,并且ename中有一个值是全数字的,若有这样的查询:
- select * from emp where ename=23456;
上面的SQL会不会出现隐式转换呢?
下面实验证明:
- MySQL [test]> select * from emp where ename='23456';
- +-------+-------+-----------+------+---------------------+------+------+--------+
- | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
- +-------+-------+-----------+------+---------------------+------+------+--------+
- | 7936 | 23456 | BOSCO-DBA | 7788 | 2014-09-13 16:13:56 | 2450 | 800 | 10 |
- +-------+-------+-----------+------+---------------------+------+------+--------+
- 1 row in set (0.00 sec)
- MySQL [test]> explain select * from emp where ename='23456'; ## 正常来说,可以使用到索引idx_ename
- +----+-------------+-------+------+---------------+-----------+---------+-------+------+-----------------------+
- | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
- +----+-------------+-------+------+---------------+-----------+---------+-------+------+-----------------------+
- | 1 | SIMPLE | emp | ref | idx_ename | idx_ename | 47 | const | 1 | Using index condition |
- +----+-------------+-------+------+---------------+-----------+---------+-------+------+-----------------------+
- 1 row in set (0.00 sec)
- MySQL [test]> select * from emp where ename=23456; ## 当varchar类型不对时,仍然是可以查出结果
- +-------+-------+-----------+------+---------------------+------+------+--------+
- | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
- +-------+-------+-----------+------+---------------------+------+------+--------+
- | 7936 | 23456 | BOSCO-DBA | 7788 | 2014-09-13 16:13:56 | 2450 | 800 | 10 |
- +-------+-------+-----------+------+---------------------+------+------+--------+
- 1 row in set, 14 warnings (0.00 sec)
- MySQL [test]> explain select * from emp where ename=23456; ## 当varchar类型不匹配时,索引无效了,选择了全表扫描
- +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
- | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
- +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
- | 1 | SIMPLE | emp | ALL | idx_ename | NULL | NULL | NULL | 15 | Using where |
- +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
- 1 row in set (0.00 sec)
可见,如果是字符类型,当出现类型不一致时,是会影响索引的使用的,会产生隐式转换的。
blog地址:http://blog.csdn.net/hw_libo/article/details/39252427
-- Bosco QQ:375612082
---- END ----
-------------------------------------------------------------------------------------------------------
版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!
转载于:https://www.cnblogs.com/Dennis-mi/articles/6089747.html
也议MySQL中隐式转换相关推荐
- 令人炸毛儿的MySQL隐式转换 - 无形之刃,最为致命
小伙伴想精准查找自己想看的MySQL文章?喏 → MySQL江湖路 | 专栏目录 我相信90%以上的同学们在平时开发时,或多或少都被隐式转换(CONVERT_IMPLICIT)坑过,甚至测出bug ...
- mysql 隐式失误_评“MySQL 隐式转换引起的执行结果错误”
今天看到一篇关于MySQL隐式转换引发执行结果错误的文章: ====================================================================== ...
- MySQL 隐式转换 字符串和整型说明
MySQL 隐式转换 字段类型定义 CREATE TABLE `user` (`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '编号',/* ...... * ...
- mysql not in 转化_解析MySQL隐式转换问题
一.问题描述 root@mysqldb 22:12: [xucl]> show create table t1G *************************** 1. row ***** ...
- mysql数据库隐式表_解析MySQL隐式转换问题
一.问题描述 root@mysqldb 22:12: [xucl]> show create table t1\G *************************** 1. row **** ...
- html中隐式转换成数字,详解JS中的隐式类型转换
JS中隐式类型转换 JS中的数据类型 JS中的数据类型分为两大类: 1.基本数据类型: 1.String 字符串 表示一段文本,例如:人的姓名.地址等 2.Number 数值 3.Boolean 布尔 ...
- mysql日期隐式转换_关于MySQL隐式转换
一.如果表定义的是varchar字段,传入的是数字,则会发生隐式转换. 1.表DDL 2.传int的sql 3.传字符串的sql 仔细看下表结构,rid的字段类型: 而用户传入的是int,这里会有一个 ...
- mysql隐式转换造成索引失效的事故总结
隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误. 由于表的字段tu_mdn定义为varchar2(20),但在查询时把该字段作为number类型以where条件传给mysql,这样 ...
- mysql 隐式转换 索引_MySQL性能优化:MySQL中的隐式转换造成的索引失效
数据库优化是一个任重而道远的任务,想要做优化必须深入理解数据库的各种特性.在开发过程中我们经常会遇到一些原因很简单但造成的后果却很严重的疑难杂症,这类问题往往还不容易定位,排查费时费力最后发现是一个很 ...
最新文章
- 京东广告典型源码示例二
- python3 递归函数的理解
- Matrix Completion with Noise
- Jira 的 数据库备份恢复 简单过程
- 为什么byte取值-128~127??
- C/C++中volatile关键字的作用
- 京东总部大厦已经完成5G信号覆盖 网速是4G的20倍!
- PyTorch: torch.optim 的6种优化器及优化算法介绍
- 什么是今日头条下拉词下拉框?
- css中的 font 与 font-size
- IDEA导入Git中项目
- Excel 常用函数和公式
- 存在哪些域名后缀种类?哪个后缀比较好?
- 几点思考-人生哲学,生活方式---ShinePans
- Docker镜像无法被删除的解决方法
- 【MySQL】查看mysql的warnings
- 基于jws发布webservice服务
- 【程序人生】这是 2017 关于程序员薪酬最详尽的调查报告
- java左手画圆右手画方_左手画圆、右手画方,双手齐用同时养护、开发你的左右大脑!...
- bm17bm6bm18