文章详情

短信预约信息系统项目管理师 报名、考试、查分时间动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MySQL45讲之函数转换导致不使用索引 - flowers

2022-02-20 17:43

关注

MySQL45讲之函数转换导致不使用索引 - flowers

本文介绍三种因为函数转换导致不使用索引的问题。

前言

本文介绍三种因为函数转换导致不使用索引的问题。注意,不使用索引指的是不使用树搜索,而是全表扫描索引树。

显式使用函数

比如 select count(*) from tradelog where month(t_modified)=7;,在 t_modified 字段上建立了普通索引。
索引对于 t_modified 是有序的,但是对于 month(t_modified) 不是有序的,所以优化器规定,当遇到使用函数对字段进行操作后,不会使用树搜索,而是全表扫描。这里因为只查询符合条件的行数,并且 t_modified 索引树比主键索引树小,所以使用了索引覆盖。

类型转换

比如 select * from tradelog where tradeid=110717;,其中,tradeid 字段是 varchar 类型。
因为 tradeid 和 110717 两个类型不一致,所以需要类型转换。那是转换成字符串呢还是数字呢?
一个简单的判断方法是,执行 select 9 < "10";,如果返回 1,说明转换成数字,否则转换成字符串。

于是,这条语句等价于 select * from tradelog where CASE(tradeid AS signed int)=110717;,也不能使用树搜索,尽管 tradeid 字段有索引。

不过,对于 select * from t where id = "1"; ,会使用主键索引,因为等价于 select * from t where id = CAST("1" AS signed int);

编码转换

比如 select * from trade_detail where tradeid=$L2.tradeid.value;,其中 tradeid 是 utf8 编码,而 $L2.tradeid.value 是 utf8mb64 编码。
因为 utf8mb64 是 utf8 的超集,所以查询时需要将 tradeid 字段编码转换成 utf8mb64。

如果要优化这个场景,在线上数据量不大且可以做这个 DDL 时,可以将 trade_detail 表的 tradeid 字段设为 utf8mb64 编码。如果不能做这个 DDL 操作,可以采用 select * from trade_detail where CONVERT(tradeid USING utf8)=$L2.tradeid.value;

总结

在遇到显式或者隐式使用函数应用字段时,优化器将不会选择索引,而是采用全表扫描的方式。并且,对于像 where id+1=1000 的表达式同样不会采用索引,写成 where id = 1000-1 就可以,这里感觉优化器偷懒了。

参考

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯