原始SQL(截取):
on date(c.create_time) >= h1.date and date(c.create_time)<=DATE_ADD(h1.date,INTERVAL 1 day) and c.brand_name = h1.brand
这是一个jion两表的条件。很显然,条件有2个,
首先是,时间范围,c表的create_time创建日期在h1表的date日期之间。
其次是,c表的brand_name 和 h1表的brand_name一样。
但是,此表索引字段的(c.create_time),被这条SQL破坏掉了。
为什么会破坏呢?
因为,
函数转换的问题:在查询条件中使用函数对索引字段进行转换,例如将c.create_time转换成日期格式,会使得索引无法直接匹配转换后的值。索引是根据原始列值构建的,而不是根据转换函数的结果构建的。
优化器限制:数据库优化器在执行查询时会根据统计信息和查询计划生成最优的执行策略。当我们使用了函数转换时,优化器无法准确预估转换后的值的分布情况,从而可能无法正确估算索引的选择性。这会导致优化器选择不使用索引,而是执行全表扫描的操作,从而降低查询性能。
优化后的SQL(截取):
on c.create_time>= h1.date and c.create_time<=DATE_ADD(h1.date,INTERVAL 1 day) and c.brand_name = h1.brand
尽管这条SQL的连接条件中,使用了函数DATE_ADD对时间列进行了加减运算,但是MySQL仍然有可能使用索引来加速连接操作。
具体来说,如果create_time列上的索引采用B-Tree索引类型,并且索引中的存储方式是时间戳,MySQL可以使用索引来查找符合条件的记录。
这样,就可以在原始列上,比较时间,不会破坏c.create_time的索引。