(二)为什么这些sql语句逻辑相同,性能却差异巨大?

1.条件字段函数操作

现在已经记录了从2016年初到2018年底的所有数据,运营部门有一个需求是,要统计发
生在所有年份中7月份的交易记录总数。这个逻辑看上去并不复杂,你的SQL语句可能会这么
写:

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

根据上图的索引规则显示,这条sql查询会降低性能,因为当month=7时,数据库索引库蒙逼了,不知所谓了,

但是你要随着数据库的索引库的信息去改变一下sql语句:

> 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');

性能会提升好多,一方面是索引库直接影响了查询性能,但是更重要的是

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

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

MySQL的优化器确实有“偷懒”的嫌疑,即使简单地把where id+1=1000改写成where id=1000-1就
能够用上索引快速查找,也不会主动做这个语句重写。

2.隐式类型转换

mysql> select * from tradelog where tradeid=110717;

两边的类型不一样引发类型转换,一旦发生类型转换了,数据库就不再根据索引查找数据了,就需要走全盘扫描了;

对于优化器来说,我们上边写的sql语句相当于

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

改善:

select * from tradelog where id="83126";

3.隐士字符编码转换

这张图是两张表的数据根据id查询数据

正如下面的sql语句:

select d.* from tradelog l, trade_detail d where d.tradeid=l.tradeid and l.id=2;

此sql语句,是先遍历id ,然后拿着id再去取第二张表的对应,获取第二张表的的id,然后发现获取的id不是想要的数据,所以便是id.value   ,进行了第四步操作,然后发生了数据编码格式转换。

改善:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值