MySQL是当下最流行的关系型数据库之一,互联网高速发展的今天,MySQL数据库在电商、金融等诸多行业的生产系统中被广泛使用。
在实际的开发运维过程中,想必大家也常常会碰到慢SQL的困扰。一条性能不好的SQL,往往会带来过大的性能开销,进而引起整个操作系统资源的过度使用,甚至造成会话堆积,引发线上故障。
而在SQL调优的场景中,一类比较常见的问题,就是隐式类型转换。那什么是隐式转换呢?
在MySQL中,当操作符与不同类型的操作数一起使用时,会发生类型转换以使操作数兼容,此时则会发生隐式转换。出现隐式转换,往往意味着SQL的执行效率将大幅降低。
接下来笔者将结合几大常见场景,让大家实际体会什么是隐式转换,以及如何去应对出现隐式转换的情况,请阅读以下案例。
传递数据类型和字段类型不一致造成隐式转换
一类比较经典的场景就是传递数据类型和字段类型不一致造成的隐式转换,这种场景也是我们平时最常遇到的。具体可以看下下面这个例子:
1) 待优化场景
SQL及执行计划如下:
select * from dt_t1 where emp_no = 41680;
该表索引如下:
key idx_empno (`emp_no`)
2)场景解析
从执行计划中Type部分:ALL,全表扫描,而没有走idx_empno索引, 一般这种情况可能传递的数据类型和实际的字段类型不一致,那么我们来看下具体的表结构。
root@localhost mysql.sock 5.7.28-log :[employees] 14:48:10>desc employees;
+------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| emp_no | varchar(14) | NO | MUL | NULL | |
| birth_date | date | NO | | NULL | |
| first_name | varchar(14) | NO | | NULL | |
| last_name | varchar(16) | NO | | NULL | |
| gender | enum('M','F') | NO | | NULL | |
| hire_date | date | NO | | NULL | |
+------------+---------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
表结构中看到该字段类型为varchar 类型,传递字段为整型,造成隐式转换不能走索引。
3)场景优化
该SQL可通过简单改写来避免出现隐式转换,如下ÿ