UNION报错列数不匹配因各SELECT字段数量不等;UNION去重开销大,UNION ALL仅追加;EXPLAIN不显示全部执行计划,需单独分析;字符集冲突需显式指定COLLATE。
UNION 报错说列数不匹配?最常见的是两个 SELECT 返回的字段数量不一致,MySQL 会直接报错 ERROR 1222 (21000): The used SELECT statements have a different number of columns。这不是类型问题,是纯数量对不上。
SELECT 的 SELECT 子句,数清楚逗号分隔的表达式个数(* 算作一个,但实际展开后必须和另一侧列数一致)SELECT * 和 SELECT a,b,c 混用 —— 表结构一旦变更,* 展开列数可能突变NULL 或 '' 占位,但需注意类型隐式转换:比如 SELECT id, name FROM t1 UNI
ON SELECT id, 0 FROM t2 可能因 name 是 VARCHAR 而 0 被转成字符串,但更稳妥的是显式写 CAST(0 AS CHAR)
UNION ALL 和 UNION 性能差十倍?不是“差十倍”,而是去重逻辑本身开销巨大:UNION 需构建临时唯一哈希表或排序去重,而 UNION ALL 只是追加结果集。尤其当结果行数过万、字段含长文本或无索引时,差异立刻暴露。
set(tuple(row) for row in results))UNION,确保参与查询的字段在各自表上有合适索引,减少中间结果体积UNION 外再套一层 ORDER BY —— MySQL 5.7+ 允许只在最后加 ORDER BY,但若提前加了子查询排序,可能触发额外临时表UNION 各部分的实际执行计划?MySQL 的 EXPLAIN 对集合操作支持有限:它只显示第一个 SELECT 的执行计划,后续部分完全不展示。不能靠它判断第二段是不是全表扫描。
SELECT 单独拎出来跑 EXPLAIN FORMAT=TREE(8.0+)或 EXPLAIN FORMAT=TRADITIONAL,逐个看 type、rows、Extra
SELECT ... INTO OUTFILE 或临时表分别保存各部分结果,对比行数和数据分布,快速定位哪一段膨胀得离谱long_query_time = 0,抓取完整 SQL 执行耗时,再结合 SHOW PROFILE FOR QUERY N(需先 SET profiling = 1)看各阶段耗时占比UNION 直接失败?错误信息通常是 ERROR 1267 (HY000): Illegal mix of collations。本质是两个结果集的字段用了不同校对规则(如 utf8mb4_0900_as_cs vs utf8mb4_general_ci),MySQL 无法自动统一比较逻辑。
SHOW FULL COLUMNS FROM table_name LIKE 'col_name',看 Collation 列SELECT 中用 COLLATE utf8mb4_0900_as_cs 显式指定,例如 SELECT name COLLATE utf8mb4_0900_as_cs FROM t1
ALTER TABLE t1 MODIFY name VARCHAR(100) COLLATE utf8mb4_0900_as_cs,但需评估存量数据影响SELECT 单独执行是否真的返回预期结构和数据量。很多人一上来就改 UNION 写法,却没发现其中一段 SQL 本身已因 JOIN 条件错误返回了几百万行。