【MySQL 源码】UNION 比 UNION ALL 的性能差很多吗?

发布时间:2023-12-25 08:30

原文地址: 【MySQL 源码】UNION 比 UNION ALL 的性能差很多吗?

欢迎访问我的个人博客: http://blog.duhbb.com/

引言

本文从源码角度分析了一下 MySQL 中 union 和 union all 的区别;得出了以下结论: union 和 union all 都会创建临时表, 但是又不太一样; 二者的查询计划不一样;union 默认会创建一个以返回列作为 key 的临时表, 所谓过滤就是将数据插入这个临时表; 临时表装数据的容器实际上是一个 unordered_set; 有一种存储引擎叫做临时表; union all 则是直接读取表的数据并返回给客户端, 不走临时表; union all 和 union 的场景还是得根据需要来判断, 如果没有 distinct 的需求话, 数据又不多, 可以考虑使用 union all.

Union 和 Union All 的区别

Union 和 Union All 之间的唯一区别是 Union All 不会删除重复的行或记录, 而是从所有表中选择满足您的具体查询条件的所有行并将它们组合到结果表中.

UNION 不适用于具有文本数据类型的列. 而 UNION ALL 适用于所有数据类型列.

MySQL 官方介绍

MySQL 官方文档在介绍 12.5 Non-Subquery UNION Execution 是这么说的:

非子查询联合 (non-subquery unions) 是在 mysql_union() 的帮助下完成的.

目前, 它分为以下步骤:

  • st_select_lex_unit::prepare(对于对单个 SELECT 的派生表可以调用相同的过程, 我们在此过程中支持它, 但我们不会在这里描述它):

    • 创建 select_union (继承自 select_result), 将在此临时表中写入选择结果, 临时表条目为空. 我们将需要在这个对象存储在它上面的每个 JOIN 结构, 但我们 (还没有) 临时表结构.
    • 分配 JOIN 结构并为每个 SELECT 执行 JOIN::prepare() 以获取有关 SELECT 列表元素类型 (结果) 的完整信息. 在此循环中完成合并结果字段类型以及存储在特殊项目 ( Item_type_holder) 中. 此操作的结果 (结果字段类型列表) 将存储在 st_select_lex_unit::types 中.
    • 创建一个临时表用于存储联合结果 (如果 UNION 没有 ALL 选项, 'distinct' 参数将传递给表创建过程).
    • 为第一步中创建 select_union 的对象分配一个临时表 .

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号