suchen

Heim  >  Fragen und Antworten  >  Hauptteil

mysql – Für diese beiden SQL-Anweisungen verwendet die eine „or“ und die andere „union all“. Die Leistung sollte besser sein als bei letzterem, oder?

explain select * from ecs_ad where ad_id =1 or ad_id = 3;
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------+
| id | select_type | table  | type  | possible_keys | key     | key_len | ref  | rows | Extra                 |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------+
|  1 | SIMPLE      | ecs_ad | range | PRIMARY       | PRIMARY | 2       | NULL |    2 | Using index condition |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------+
1 row in set

Das ist Union all

explain select * from ecs_ad where ad_id = 4 union all select * from ecs_ad where ad_id = 3;
+------+--------------+------------+-------+---------------+---------+---------+-------+------+-----------------+
| id   | select_type  | table      | type  | possible_keys | key     | key_len | ref   | rows | Extra           |
+------+--------------+------------+-------+---------------+---------+---------+-------+------+-----------------+
|    1 | PRIMARY      | ecs_ad     | const | PRIMARY       | PRIMARY | 2       | const |    1 | NULL            |
|    2 | UNION        | ecs_ad     | const | PRIMARY       | PRIMARY | 2       | const |    1 | NULL            |
| NULL | UNION RESULT | <union1,2> | ALL   | NULL          | NULL    | NULL    | NULL  | NULL | Using temporary |
+------+--------------+------------+-------+---------------+---------+---------+-------+------+-----------------+
3 rows in set
PHPzPHPz2747 Tage vor1161

Antworte allen(2)Ich werde antworten

  • PHPz

    PHPz2017-05-18 10:58:52

    首先,这两个查询性能差距应该不大。
    因为 ad_id 列是主键.

    根据 type 列分析:
    or 查询,type:range
    union all 查询:type:const / const / ALL

    首先可以确认的是,const 要优于 range.
    const 也是因为 ad_id 为主键.

    但是 union all 做了三次操作,两次主键或者唯一索引查询 type:const,但最后组合到一起时 type:ALL
    type:ALL 本身性能比 range 还要差

    从 Type 看,or 查询性能应该更好.

    Extra 分析
    or 查询:Using index condition
    union all 查询:NULL / NULL / Using temporary

    Using index condition 为 MySQL 5.6 版本以后新添加的特性,索引条件推送。

    首先说一下没有索引条件推送时候的处理流程:

    优化器没有使用ICP时,数据访问和提取的过程如下:

    1) 当storage engine读取下一行时,首先读取索引元组(index tuple),然后使用索引元组在基表中(base table)定位和读取整行数据。
    2) sever层评估where条件,如果该行数据满足where条件则使用,否则丢弃。
    3) 执行1),直到最后一行数据。

    当存在索引条件推送时候的处理流程:

    优化器使用ICP时,server层将会把能够通过使用索引进行评估的where条件下推到storage engine层。数据访问和提取过程如下:

    1) storage engine从索引中读取下一条索引元组。
    2) storage engine使用索引元组评估下推的索引条件。如果没有满足wehere条件,storage engine将会处理下一条索引元组(回到上一步)。只有当索引元组满足下推的索引条件的时候,才会继续去基表中读取数据。
    3) 如果满足下推的索引条件,storage engine通过索引元组定位基表的行和读取整行数据并返回给server层。
    4) server层评估没有被下推到storage engine层的where条件,如果该行数据满足where条件则使用,否则丢弃。

    简单来说,没有 ICP 时,存储引擎返回所有满足条件的整行数据,在 service 层进行 where 条件过滤。
    有 ICP 时,where 条件下推到存储引擎层,存储引擎直接返回满足条件的数据。
    性能自然提高很多。

    对于 ICP 的相关介绍,可以查看这里

    而 Using temporary 表示隐式临时表,意思是 MySQL 会在产生一个临时表,存放中间数据。因为 union all 是分开处理,最后合并的关系。
    从 Extra 看,也应该是 or 查询性能更高。

    综合来看:OR 查询的性能应该有优于 UNION ALL .

    由于所有查询性能都随着数据量增大而变化,以上分析只是单看题主所贴的 Explain 分析结果。也并不是说 OR 在所有情况下都优于 UNION ALL。

    以上为个人意见,如有错误,请指正。

    Antwort
    0
  • 黄舟

    黄舟2017-05-18 10:58:52

    这两个语句,无区别。
    一般or连接两个不同字段,无法使用索引的时候,性能会比较差,不如union,可以尝试修改。

    Antwort
    0
  • StornierenAntwort