当前位置: 首页 > news >正文

MySQL的Union和OR查询

这里写目录标题

      • **1. 创建表和索引**
      • **2. 编写 `UNION` 查询**
      • **3. 使用 `EXPLAIN` 分析查询**
      • **4. 分析 `EXPLAIN` 结果**
        • **可能的结果分析**:
      • **5. 验证索引合并**
      • **总结**
      • **1. `UNION` 操作的分析**
        • **为什么使用临时表?**
      • 2. `OR` 条件的分析
        • 为什么使用索引合并?
      • 3. `UNION` 和 `OR` 的区别
      • **总结**

在 MySQL 中, UNION 操作通常用于合并两个查询的结果集。为了测试 UNION 操作是否会使用索引合并(Index Merge)功能,还是仅使用单列索引,可以按照以下步骤进行测试和分析。


1. 创建表和索引

根据表结构,为 phoneemail 列创建单列索引:

CREATE INDEX idx_phone ON tb_user(phone);
CREATE INDEX idx_email ON tb_user(email);

2. 编写 UNION 查询

编写一个 UNION 查询,分别基于 phoneemail 列进行查询:

SELECT * FROM tb_user WHERE phone = '12345678901'
UNION
SELECT * FROM tb_user WHERE email = 'example@example.com';

3. 使用 EXPLAIN 分析查询

使用 EXPLAIN 命令查看查询的执行计划,判断是否使用了索引合并功能:

EXPLAIN
SELECT * FROM tb_user WHERE phone = '12345678901'
UNION
SELECT * FROM tb_user WHERE email = 'example@example.com';

4. 分析 EXPLAIN 结果

EXPLAIN 的输出中,重点关注以下字段:

  • type:访问类型,ref 表示使用了索引。
  • key:使用的索引名称。
  • Extra:额外信息,如果出现 Using unionUsing index merge,则表示使用了索引合并。
可能的结果分析
  1. 仅使用单列索引

    • 每个子查询的 typerefkeyidx_phoneidx_email
    • Extra 中没有 Using index merge
    • 说明每个子查询分别使用了 phoneemail 的单列索引。
  2. 使用了索引合并

    • typeindex_merge
    • key 可能显示 idx_phone,idx_email
    • Extra 中显示 Using union(idx_phone,idx_email)
    • 说明 MySQL 使用了索引合并功能。

5. 验证索引合并

如果 EXPLAIN 结果显示没有使用索引合并,可以尝试强制使用索引合并:

SELECT * FROM tb_user WHERE phone = '12345678901' OR email = 'example@example.com';

然后再次使用 EXPLAIN 分析:

EXPLAIN
SELECT * FROM tb_user WHERE phone = '12345678901' OR email = 'example@example.com';

观察是否使用了索引合并。
type:index_merge
在这里插入图片描述


总结

  • 使用 EXPLAIN 分析查询计划。
  • 如果 EXPLAINExtra 字段显示 Using index merge,则使用了索引合并功能。
  • 如果每个子查询分别使用了单列索引,则说明没有使用索引合并。

通过以上方法,可以测试并判断 UNION 操作是否使用了索引合并功能。

实操之后

mysql> EXPLAIN
-> SELECT * FROM tb_user WHERE phone = '12345678901'
-> UNION
-> SELECT * FROM tb_user WHERE email = 'example@example.com';
+----+--------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-----------------+
| 1 | PRIMARY | tb_user | NULL | ref | idx_phone | idx_phone | 35 | const | 1 | 100.00 | NULL |
| 2 | UNION | tb_user | NULL | ref | idx_email | idx_email | 303 | const | 1 | 100.00 | NULL |
| NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-----------------+

在这里插入图片描述

EXPLAIN 的结果可以看出,UNION 操作和 OR 条件的执行计划有所不同。以下是详细解释:


1. UNION 操作的分析

UNION 操作的执行计划分为三个部分:

  • 第一部分SELECT * FROM tb_user WHERE phone = '12345678901'
    • type: ref,表示使用了索引。
    • key: idx_phone,表示使用了 phone 列的单列索引。
    • Extra: 无额外信息。
  • 第二部分SELECT * FROM tb_user WHERE email = 'example@example.com'
    • type: ref,表示使用了索引。
    • key: idx_email,表示使用了 email 列的单列索引。
    • Extra: 无额外信息。
  • 第三部分UNION RESULT
    • type: ALL,表示需要扫描所有行。
    • Extra: Using temporary,表示使用了临时表来存储 UNION 的结果。
为什么使用临时表?

UNION 操作会将两个查询的结果集合并,并自动去除重复的行。为了实现这一点,MySQL 会将两个查询的结果存储在一个临时表中,然后对临时表进行去重操作。因此,UNION 操作通常会使用临时表。


2. OR 条件的分析

对于 OR 条件,MySQL 可能会使用索引合并(Index Merge)功能。例如:

EXPLAIN
SELECT * FROM tb_user WHERE phone = '12345678901' OR email = 'example@example.com';

执行计划可能如下:

  • type: index_merge,表示使用了索引合并。
  • key: idx_phone,idx_email,表示同时使用了 phoneemail 列的单列索引。
  • Extra: Using union(idx_phone,idx_email); Using where,表示 MySQL 使用了索引合并功能,并通过 WHERE 条件过滤结果。
为什么使用索引合并?

OR 条件需要同时满足两个条件中的任意一个。MySQL 会分别使用 phoneemail 列的单列索引,然后将结果合并(Using union),最后通过 WHERE 条件过滤结果。


3. UNIONOR 的区别

特性UNIONOR
结果集合并两个查询的结果,并去重合并两个条件的结果,不去重
索引使用分别使用单列索引可能使用索引合并(Index Merge)
临时表使用临时表存储结果不使用临时表
性能可能较慢,因为需要去重和临时表操作通常更快,因为不需要去重

总结

  • UNION
    • 分别使用单列索引。
    • 使用临时表存储结果并去重。
    • 适合需要合并并去重的场景。
  • OR
    • 可能使用索引合并(Using union)。
    • 不需要临时表,性能通常更好。
    • 适合需要同时满足多个条件的场景。

根据实际需求选择合适的查询方式。如果需要去重,使用 UNION;如果不需要去重,使用 OR

相关文章:

  • 音乐创作新纪元:AI音乐网站的革命性力量
  • 大屏开源项目go-view二次开发1----环境搭建(C#)
  • AF3 make_template_features函数解读
  • 蓝桥杯备赛-基础训练(三)哈希表 day15
  • 特征提取:如何从不同模态中获取有效信息?
  • 中兴B863AV3.2-T/B863AV3.1-T2/B863AV3.1-T2K_电信高安_S905L3A-B_安卓9.0_线刷固件包
  • Python进行简单医学影像分析的示例
  • LLM Agent:PaSa
  • ipad连接电脑断断续续,不断弹窗的解决办法
  • 计算机专业知识【Excel 引用大揭秘:相对、绝对与混合引用】
  • 抓包工具(三)Wireshark代理抓包Java程序的HTTPS请求
  • 编程考古-忘掉它,Delphi 8 for the Microsoft .NET Framework
  • 城市地质调查信息化建设,数字化时代的城市规划利器
  • C#DevExpress使用GridLookUpEdit实现订单明细选择商品
  • 大数据之常用Linux操作
  • 内外网文件传输 安全、可控、便捷的跨网数据传输方案
  • 商业航天级微控制器单元(MCU)技术特征分析
  • 微服务框架及其中出现的各种问题和对应的解决方案/组件
  • element ui的time时间和table表格
  • Windows逆向工程入门之结构体类特性分析
  • 告别户口本!今天起婚姻登记实现全国通办
  • 匈牙利外长称匈方已驱逐两名乌克兰外交官
  • 上汽享道出行完成13亿元C轮融资,已启动港股IPO计划
  • 长江画派创始人之一、美术家鲁慕迅逝世,享年98岁
  • 新买宝马竟是“维修车”,男子发视频维权被4S店索赔100万
  • 早期投资人蜂巧资本清仓泡泡玛特套现超22亿港元,称基金即将到期