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

            

  • 相关阅读:
    codeforces484A
    codeforces559B
    spfa算法及判负环详解
    清北学堂提高组突破营考试T1
    lemon用法
    清北学堂提高组突破营游记day6
    清北学堂提高组突破营游记day5
    POJ-1679 The Unique MST (判断最小生成树的唯一性)
    HDU 4553 约会安排 (区间合并)【线段树】
    POJ 1236 Network Of Schools (思维+强连通)
  • 原文地址:https://www.cnblogs.com/ouhouki/p/9661927.html
Copyright © 2020-2023  润新知