MERGE算法比TEMPTABLE快,因其不创建临时表,而是将视图SQL直接展开进外层查询,仅执行一次优化与一套计划;而TEMPTABLE需先物化再二次扫描,增加IO、内存及排序开销。

MERGE算法为什么比TEMPTABLE快
因为MERGE不创建临时表,而是把视图SQL直接“展开”进外层查询,整个执行过程只走一次优化器、一套执行计划。TEMPTABLE则必须先执行视图定义、写入临时表、再对外层查询做二次扫描——多了一轮IO、内存分配和主键排序,尤其在大结果集时延迟明显。
哪些结构会让MERGE失效而退化为TEMPTABLE
MySQL对MERGE有硬性限制,只要视图定义中出现以下任一情况,ALGORITHM=MERGE声明会被忽略,自动降级为TEMPTABLE:
-
COUNT()、SUM()、AVG()等聚合函数 -
DISTINCT或GROUP BY - 子查询(包括标量子查询、FROM中的子查询)
-
UNION、LIMIT、ORDER BY(除非配合LIMIT且无歧义) - 视图列使用表达式重命名但类型不一致(如
id+0 AS id)
如何验证当前视图是否真正在用MERGE
不能只看CREATE VIEW语句里写了ALGORITHM=MERGE,得看实际执行计划:
- 对视图执行
EXPLAIN SELECT * FROM my_view WHERE ... - 如果
type列出现ALL或range,且Extra里**没有**Using temporary或DERIVED,说明MERGE生效 - 一旦看到
select_type = DERIVED,就确认被物化了——哪怕你写了ALGORITHM=MERGE也没用
强行用MERGE的实操边界在哪
不是所有场景都能靠改写绕过限制。比如把(SELECT COUNT(*) FROM t2 WHERE t2.id = t1.id)改成存储函数fn_count_t2(t1.id)后,确实能触发MERGE,但要注意:
- 函数必须是
DETERMINISTIC且READS SQL DATA,否则MySQL拒绝内联 - 函数体不能含
SELECT ... INTO或临时表操作 - 高并发下函数调用可能成为瓶颈,需压测验证QPS拐点
- 视图依赖函数,备份/迁移时要同步导出函数定义,否则
Table 'my_db.my_view' doesn't exist这类错误会突然出现
真正难的从来不是加ALGORITHM=MERGE,而是让视图SQL结构干净到能让优化器信得过——这往往意味着放弃一部分抽象便利,换回执行路径的确定性。


















