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

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


http://www.kler.cn/a/558067.html

相关文章:

  • Vite 和 Webpack 的区别和选择
  • 靶场之路-Kioptix Level-1 mod_ssl 缓冲区溢出漏洞
  • CDefFolderMenu_MergeMenu函数分析之添加了分割线和属性菜单项两项
  • 《网络安全入门实战手册》
  • 星途汽车掉队?2024销量增速回落,“星纪元”序列后劲不足
  • yum安装时使用指定的nvidia-docker.repo
  • 算法与数据结构(环形链表)
  • Redis数据库面试——数据结构类型知识
  • 市场趋势分析与交易策略优化
  • 网络安全高级软件编程技术
  • 京东外卖骑手全部缴纳五险一金
  • 【云安全】云原生-Docker(六)Docker API 未授权访问
  • 用 TensorFlow 搭建简单的手写数字识别模型
  • day56 第十一章:图论part06
  • 如何设计合理的树状结构表:平衡查询效率与维护效率
  • Uniapp 中如何将 Radio 组件圆框改为方框的方法(小程序端)
  • 区块链不可能三角
  • 基于Java实现1688淘口令真实URL获取的爬虫设计
  • python读取pdf文档
  • kotlin的Int类型调用toString()会导致空指针吗