MySQL复合索引下OR查询与拆分两次查询的性能对比
结论
带OR条件的单次查询执行耗时会明显更慢。
原因分析
方案1(带OR的单次查询)的执行逻辑:
InnoDB优化器无法为foo=1 and (bar1=2 or bar2=2)这类跨字段OR条件同时匹配foobar1、foobar2两个联合索引,绝大多数场景下会直接选择全表扫描逐行校验条件,数据量越大耗时越高。就算开启了索引合并优化,也需要先分别从两个索引读取符合条件的主键、做去重合并后再回表取数据,额外的合并计算开销也非常可观。方案2(两次独立查询)的执行逻辑:
两次查询都能完美命中对应的联合索引,走索引快速定位符合条件的行:select * from FooBar where foo=1 and bar1=2命中foobar1联合索引select * from FooBar where foo=1 and bar2=2命中foobar2联合索引
仅需要在应用层对结果做一次轻量去重(避免同时满足两个条件的行重复返回),哪怕算上两次查询的网络往返开销,总耗时也远低于方案1。
可选优化写法
如果希望用单次查询实现需求又要保证性能,可以改写为UNION的形式,性能和两次独立查询基本持平,还能自动完成去重:
select * from FooBar where foo=1 and bar1=2 UNION select * from FooBar where foo=1 and bar2=2;
内容的提问来源于stack exchange,提问作者cr001
相关产品推荐
相关产品推荐

