UNION ALL合并分表需严格对齐字段数量、顺序和类型,显式补NULL并转换类型,WHERE条件必须下推至各子查询,禁止视图内GROUP BY,ORDER BY仅限末尾且需TOP (100) PERCENT,同时更新统计信息以防优化器误判。

视图里直接用 UNION ALL 合并分表是可行的,但只要字段对不齐、条件没下推、或忘了排序,一查就报错或性能崩盘。
字段数量、顺序、类型必须手动对齐
SQL Server 视图不会自动帮你补列、转类型或重命名。两个子查询列数不等、同位置列类型不兼容(比如 INT 和 VARCHAR),建视图时就会报 ERROR 1222。
- 统一列名:用别名强制一致,如都写成
id,name,amount - 缺列补
NULL并显式转换:比如分表 A 有amount,B 没有,就得写CAST(NULL AS DECIMAL(18,2)) AS amount - 避免隐式转换陷阱:
VARCHAR(10)和VARCHAR(50)虽兼容,但 SQL Server 会按更长的长度分配内存,影响后续聚合性能
WHERE 条件必须下沉到每个子查询
外层加 WHERE dt >= '2026-05-01' 看似省事,实际会让 SQL Server 先全量扫描所有分表再过滤,索引完全失效。
- 正确写法:每个
SELECT分支都带独立WHERE,且确保各分表的dt字段类型一致(DATEvsDATETIME2不兼容) - 注意分区键是否被索引:如果分表按
dt分区,但某张表没在该字段建索引,那这一支仍会走全表扫描 - 测试执行计划:建好视图后,用
SET STATISTICS XML ON查看是否每支都命中了预期索引
视图定义里不能直接 GROUP BY 或 ORDER BY(除非在最外层)
UNION ALL 是集合操作,语法优先级低于 GROUP BY,所以 SELECT ... UNION ALL SELECT ... GROUP BY 会直接报错。
- 想聚合:必须套子查询,例如
SELECT type, SUM(val) FROM (SELECT 'A' AS type, val FROM t_a UNION ALL SELECT 'B', val FROM t_b) AS src GROUP BY type - 想排序:只能在视图定义末尾加一个
ORDER BY,且必须配合TOP (100) PERCENT(SQL Server 要求),否则建视图失败 - 别依赖视图自带顺序:即使建视图时写了
ORDER BY,下游应用再查这个视图时,结果仍可能无序——必须在外层查询再写一遍ORDER BY
最容易被忽略的是字段类型对齐后的隐式精度损失,比如把 REAL 和 DECIMAL(10,2) 强行 UNION ALL,SQL Server 会升格为 REAL,小数位直接截断;还有就是每个分表的统计信息是否最新——过期的统计信息会让优化器误判,选错执行路径,哪怕字段和条件都对了,照样慢得离谱。

















