MySQL实战 | 18 为什么这些SQL语句逻辑相同,性能却差异巨大?

在 MySQL 中,有很多看上去逻辑相同,但性能却差异巨大的 SQL 语句。对这些语句使用不当的话,就会不经意间导致整个数据库的压力变大。

案例一:条件字段函数操作

假设有如下语句,并且字段 t_modified 上有索引:

mysql> select count(*) from tradelog where month(t_modified)=7;

那么这条语句会很快地返回数据吗?

答案是否定的。

对索引字段做函数操作,可能会破坏索引值的有序性,因此优化器就会放弃走树索引。

这里,由于加了 month() 函数操作,MySQL 无法再使用索引快速定位功能,而只能使用全索引扫描。

语句优化:

mysql> select count(*) from tradelog where
    -> (t_modified >= '2016-7-1' and t_modified<'2016-8-1') or
    -> (t_modified >= '2017-7-1' and t_modified<'2017-8-1') or 
    -> (t_modified >= '2018-7-1' and t_modified<'2018-8-1');

案例二:隐式类型转换

有如下语句:

mysql> select * from tradelog where tradeid=110717;

tradeid 字段是 varchar(32) 类型的,而对比的参数是整数,所有就需要做类型转换。

1、数据类型转换的规则是什么?

select "10" > 9 的结果:

① 如果结果是 1,那么就是将字符串转换成数字
② 如果结果是 0,那么就是将数字转换成字符串

如果是将字符串转换成数字,那么上面的语句对应的就是:

mysql> select * from tradelog where  CAST(tradid AS signed int) = 110717;

其实就出发了案例一里面的规则,对字符串索引进行了函数操作,优化器就会放弃树搜索的功能,进行全表搜索。

案例三:隐式字符编码转换

如下语句:

mysql> select d.* from tradelog l, trade_detail d where d.tradeid=l.tradeid and l.id=2; /* 语句 Q1*/

如果表 tradelog(utf8) 和表 trade_detail(utf8mb4) 的字符集不同,那么 d.tradeid=l.tradeid 条件也会导致全表扫描。

字符集 utf8mb4 是 utf8 的超集,所以当这两个类型的字符串在做比较的时候,MySQL 内部的操作是,先把 utf8 字符串转成 utf8mb4 字符集,再做比较。

同样,触发了案例一中的条件。


你的关注是对我最大的鼓励!

关注本公众号,后台回复「2018」即可获取传智播客 2018 最新 Python 和 Java 教程。

公众号提供CSDN资源免费下载服务!


©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 转 # https://www.cnblogs.com/easypass/archive/2010/12/ 08/...
    吕品㗊阅读 13,342评论 0 44
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 11,017评论 0 9
  • 本文主要总结了工作中一些常用的操作及不合理的操作,在对慢查询进行优化时收集的一些有用的资料和信息,本文适合有MyS...
    Chting阅读 3,790评论 0 1
  • MySQL数据库对象与应用 2.1-MySQL数据类型 库建立好之后基本不动,和我们接触最频繁的是表. 建表就是声...
    极客圈阅读 6,523评论 0 8
  • MYSQL应该是最流行的WEB后端数据库。大量应用于PHP,Ruby,Python,Java 等Web语言开发项目...
    smooth00阅读 7,555评论 0 16

友情链接更多精彩内容