条件字段函数操作

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

month(t_modified) 导致t_modified的字段失效了。

  • 如果对字段做了函数计算,就用不上索引了,这是MySQL的规定。
  • 为什么条件是where t_modified=’2018-7-1’的时候可以用上索引,而改成where month(t_modified)=7的时候就不行了?
    • 索引失效 - 图1
    • 这个t_modified索引的示意图。方框上面的数字就是month()函数对应的值。
    • 如果你的SQL语句条件用的是where t_modified=’2018-7-1’的话,引擎就会按照上面绿色箭头的路线,快速定位到 t_modified=’2018-7-1’需要的结果。
    • 计算month()函数的话,你会看到传入7的时候,在树的第一层就不知道该怎么办了。
    • B+树提供的这个快速定位能力,来源于同一层兄弟节点的有序性。对索引字段做函数操作,可能会破坏索引值的有序性,因此优化器就决定放弃走树搜索功能。

隐式类型转换

  1. mysql> select * from tradelog where tradeid=110717;

tradeid的字段类型是varchar(32),而输入的参数却是整型,所以需要做类型转换。
MySQL的优化器确实有“偷懒”的嫌疑,即使简单地把where id+1=1000改写成where id=1000-1就能够用上索引快速查找,也不会主动做这个语句重写。
因为要求在索引字段上做函数操作而导致了全索引扫描。

隐式字符编码转换

因为要求在索引字段上做函数操作而导致了全索引扫描。