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

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

CREATE TABLE `tradelog` (
  `id` int(11) NOT NULL,
  `tradeid` varchar(32) DEFAULT NULL,
  `operator` int(11) DEFAULT NULL,
  `t_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `tradeid` (`tradeid`),
  KEY `t_modified` (`t_modified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

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

对于如下语句

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

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

需要注意的是,优化器并不是要放弃使用这个索引。在这个例子里,放弃了树搜索功能,优化器可以选择遍历主键索引,也可以选择遍历索引 t_modified,优化器对比索引大小后发现,索引 t_modified 更小,遍历这个索引比遍历主键索引来得更快。因此最终还是会选择索引 t_modified。
image

案例二:隐式类型转换

select * from tradelog where tradeid=110717;

交易编号 tradeid 这个字段上,本来就有索引,但是 explain 的结果却显示,这条语句需要走全表扫描。这是因为,tradeid 的字段类型是 varchar(32),而输入的参数却是整型,所以需要做类型转换。

MySQL 中,字符串和数字做比较的话,是将字符串转换成数字。

上面的语句实际上相当于

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

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

字符集不同只是条件之一,连接过程中要求在被驱动表的索引字段上加函数操作,是直接导致对被驱动表做全表扫描的原因。

posted @ 2023-07-02 18:46  LionelYee  阅读(5)  评论(0编辑  收藏  举报