You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无表结构变更场景下如何优化MySQL多表UNION去重查询?

MySQL多表UNION去重查询优化方案

1. 最优索引优化方案

  • 给每张表建立 (UserID, Period)联合覆盖索引,不属于修改表字段逻辑结构的范畴,完全符合你的约束要求。该索引可以直接匹配查询过滤条件(WHERE UserID = :user),同时直接从索引中返回Period字段值,完全避免回表查询原数据,查询效率会有数量级提升。
  • 由于联合索引中同一个UserID下的Period是有序存储的,MySQL可以在索引层面直接完成单表内的Period去重,不需要额外生成临时表处理。

2. 查询语句优化

放弃原有的UNION自动去重逻辑,改用UNION ALL拼接所有结果后统一做一次去重排序,仅产生1次临时表开销,远低于原有多段UNION的多次去重开销,尤其在UNION子句数量多的场景(比如你测试的500张子表场景)下性能提升非常明显:

SELECT DISTINCT Period 
FROM (
    SELECT Period FROM table_1 WHERE UserID = :user
    UNION ALL
    SELECT Period FROM table_2 WHERE UserID = :user
    UNION ALL
    SELECT Period FROM table_3 WHERE UserID = :user
) AS user_periods
ORDER BY Period ASC;

你之前给每个子查询加SELECT DISTINCT的写法会让每个子查询单独生成临时表去重,加上最终UNION的全局去重,等于多了N次额外临时表操作,性能反而下降,不建议使用。

3. 表排列顺序的影响

你当前将最大的表放在最前面的做法是正确的:
不管是原有UNION写法还是优化后的UNION ALL写法,大表在前可以提前覆盖绝大多数的Period取值,后续小表合并时需要对比去重的重复值数量会大幅减少,整体去重开销更低。

MyISAM引擎适配说明

MyISAM引擎的非聚簇索引结构天然适合该覆盖索引的场景,不需要回表访问主键索引,查询性能比InnoDB下同场景还会略高;Period为VARCHAR类型不影响联合索引的使用,索引会直接存储Period的字符串值用于返回。

内容的提问来源于stack exchange,提问作者IGP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:36:03