本文整理自:袋鼠云技术荟 | SQL优化案例(2):OR条件优化html
数栈是云原生—站式数据中台PaaS,咱们在github上有一个有趣的开源项目:https://github.com/DTStack/flinkxgit
FlinkX是一个基于Flink的批流统一的数据同步工具,既能够采集静态的数据,好比MySQL,HDFS等,也能够采集实时变化的数据,好比MySQL binlog,Kafka等,是全域、异构、批流一体的数据同步引擎,你们若是有兴趣,欢迎来github社区找咱们玩~github
在MySQL中,一样的查询条件,若是变换OR在SQL语句中的位置,那么查询的结果也会有差别,在较为复杂的状况下,可能会带来索引选择不佳的性能隐患,为了不执行效率大幅度降低的问题,咱们能够适当考虑使用Union all 对查询逻辑较为复杂的SQL进行分离。sql
常见OR使用场景,请阅读如下案例:安全
1. 待优化场景app
执行计划工具
共返回1 行记录,花费 5 ms。性能
2. 场景解析测试
从查询条件中能够看出 token 和 uid 过滤性都很是好,可是因为使用了 or, 须要采用 index merge 的方法才能得到比较好的性能。但在实际执行过程当中MySQL优化器默认选择了使用registrationId 上的索引,致使 SQL 的性能不好。优化
3. 场景优化
咱们将SQL改写成union all的形式。
共返回5 行记录,花费 5 ms。
经过对比优化先后的执行计划,能够明显看出,将SQL拆分红两个子查询,再使用union对结果进行合并,稳定性和安全性更好,性能更高。
1. 待优化场景
执行计划
2. 场景解析
本例的SQL查询中有一个子查询,子查询被当成驱动表,产生了auto_key,经过SQL拆分进行测试,验证主要是(pc.count =0 , or pc.count is null )会影响到整个SQL的性能,须要进行比较改写。
3. 场景优化
首先咱们能够单独思考(pc.count =0 , or pc.count is null ) 如何进行优化?先写一个相似的SQL
这个时候咱们看到的实际上是同一个列,但对应不一样的值,这种状况能够利用case when进行转换。
再回到原始SQL进行改写。
能够看出优化后的SQL比原始SQL快了30秒,执行效率提高约50倍。
1. 待优化场景
2.场景解析
咱们仔细分析上述查询语句,发现虽然业务逻辑只须要查询半分钟内修改的数据,但执行过程却必须对全部的数据进行关联操做,带来没必要要的性能损耗。
3.场景优化
咱们对原始SQL进行拆分操做,第一部分sql-01以下:
sql-01以user_msg 表为驱动,使用gmt_modified 索引过滤最新数据。
第二部分sql-02以下:
ql-02以user为驱动表,msg user_id 的索引过滤行很好。
第三部分sql-03以下:
sql-03以group为驱动表,使用gmt_modified 索引过滤最新数据。
MySQL OR条件优化的常见场景主要有如下状况:
一、相同列能够使用IN进行代替
二、不一样列及复杂的状况下,能够使用union all 进行分离
三、关联SQL OR条件
咱们须要结合实际场景,分析优化。