• MySQL优化——or条件优化


        MySQL5.0和更新版本中引入了一种叫:索引合并(Index merge)的策略,一定程度上可以使用表上多个单列索引来定位指定的行。

        该特性主要应用于以下三种场景:

          1. 对or语句求并集,如查询select * from film_actor where c1 = "xxx" or c2 = "xxx"时,如果c1和c2列上分别有索引,可以按照c1和c2条件进行查询,再将查询结果合并(union)操作,得到最终结果。

          2. 对and语句求交集,如查询select * from film_actor where c1 = "xxx" and c2 = "xxx"时,如果c1和c2列上分别有索引,可以按照c1和c2条件进行查询,再将查询结果取交集(intersect)操作,得到最终结果。

          3. 组合前两种情况的合并及相交。

        该新特性可以在一些场景中大幅度提升查询性能,但受限于MySQL糟糕的统计信息,也导致很多查询场景查询性能极差甚至导致数据库崩溃。

          以select * from film_actor where c1 = "xxx" and c2 = "xxx"为例:

            1. 当c1列和c2列选择性较高时,按照c1和c2条件进行查询性能高且返回数据集较小,再对两个数据量较小的数据集求交集的操作成本也比较低,最终整个语句查询高效;

            2. 当c1列或c2列选择性较差且统计信息不准时,比如整表数据量1000万,按照c2列条件返回800万数据,按照c1列返回100条数据,此时按照c2列条件进行索引扫描+聚集索引查询的操作成本极高(可能是整表扫描的百倍消耗),对100

              条数据和800万数据求交集的成本也极高,最终导致整条SQL需要消耗大量CPU和IO资源,且相应时间超长,而如果值使用c1列的索引,查询消耗资源少且性能较高。

              即使用select * from film_actor where c1 = "xxx" union all select * from film_actor where  c2 = "xxx"往往更好。

          索引合并策略有时候是一种优化的结果,但实际上更多的时候说明了表上的索引建的的很糟糕:

            1、当出现服务器对多个索引做相交操作时(通常有多个and条件),通常意味着需要一个包含所有相关列的多列索引,而不是多个独立的单列索引。

            2、当服务器需要对多个索引做合并操作时(通常有多个or条件),通常需要消耗大量cpu和内存资源在算法缓存、排序和合并操作上。特别是当其中某些索引的选择性不高,需要合并扫描返回的大量数据的时候。

            3、更重要的是,优化器不会把这些计算到“查询成本”中,优化器只关心随机页面读取。这回使得查询的成本被“低估”,导致该执行计划还不如直接走全表扫描。

            

  • 相关阅读:
    linux内核启动分析(2)
    linux内核启动分析
    U-Boot启动过程完全分析<转>
    linux网桥浅析
    centeros --- dockerfile
    centeros--- docker 操作命令
    java SSM项目搭建-- The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone
    java 环境配置 -- url is not registered
    java 环境配置 -- 配置Tomcat
    java 环境配置--破解IDEA
  • 原文地址:https://www.cnblogs.com/ouhouki/p/9661927.html
Copyright © 2020-2023  润新知