• 为什么我加了索引,SQL执行还是这么慢(二)?


    接上文

    在MySQL中,有一些语句即使逻辑相同,执行起来的性能差异确实极大的。
    还记得我们上文中的结论吗:如果想使用索引树搜索功能,就不能使用数据库函数来处理索引字段值,而是在不改变索引字段值的同时,自己通过SQL语句来实现逻辑。
    而本文中,我们将基于上述结论进行分析,为什么隐式替换,不能使用索引树搜索功能。

    首先,什么是隐式替换?

    隐式替换,指的是不用我们主动去转型的数据类型转换规则。以Java代码为例:
    int intNum = 3;
    double doubleNum = 3.5;
    intNum = (int) doubleNum;
    doubleNum = intNum;
    double转int,由于丢失精度,所以要求我们去主动进行转型,而int转double,系统将进行隐式替换
    下面这条SQL就用到了隐式替换:
    select * from tradelog where tradeid=123;
    对优化器而言,这个语句相当于:
    select * from tradelog where CAST(tradid AS signed int) = 123;
    最常见的隐式替换就是字符串和数字之间的替换,MySQL会将字符串隐式替换为数字。
    我们在表中再插入5条测试数据,执行上述SQL:
    insert into tradelog (id,tradeid,t_modified) values(6,'123','2017-03-15'); 
    insert into tradelog (id,tradeid,t_modified) values(7,'123','2017-06-11'); 
    insert into tradelog (id,tradeid,t_modified) values(8,'456','2017-07-03'); 
    insert into tradelog (id,tradeid,t_modified) values(9,'456','2018-08-11');
    insert into tradelog (id,tradeid,t_modified) values(10,'789','2018-09-12');
    我们可以通过explain命令,对这行语句的执行结果进行分析。由于对索引字段值进行了函数处理,所以这条SQL会做全索引扫描。
    同理,如果想使用索引树查找,则需要去除隐式替换(其实也就是去除加载索引值上的函数):
    select * from tradelog where tradeid="123";
    接着我们使用explain对其进行分析,此时采用了树搜索的方式,只查找了2行数据:
    这里再抛出一个问题,下面这条语句是否可以使用树搜索的方式进行数据的查找?
    select * from tradelog where id = "6";
    答案是可以的,是因为MySQL的数据转换会将字符串类型值转换为数字,对于优化器而言,这条SQL等同于:
    select * from tradelog where id = cast(6 as signed int);
    可以看出,函数是加在搜索值上的,并没有加在索引值上,所以还可以使用树搜索的方式进行查找。
    我们使用explain来看一下SQL执行结果:
    所以并不是所有的隐式替换都不能使用索引的树查找,需要具体分析(函数的位置;字符串和数字同时存在,字符串会转换成数字),当然,不在SQL中出现隐式替换是最好的方式,便于记忆。
     
     

  • 相关阅读:
    使用zinnia制作android手写输入功能(上)编译zinnia
    Raphael实例
    正则表达式 笔记
    已知弧长和弦长求半径
    Raphael参考 翻译完毕
    在chorme中查找多余的css规则
    CSS3中Transform
    手机移动端WEB资源整合
    JS判断移动设备最佳方法 并实现跳转至手机版网页
    让IE和Firefox兼容的CSS技巧集合css hack
  • 原文地址:https://www.cnblogs.com/nedulee/p/11834147.html
Copyright © 2020-2023  润新知