CREATE VIEW
或 ALTER VIEW
的可选 ALGORITHM
子句是 MySQL 对标准 SQL 的扩展。它会影响 MySQL 处理视图的方式。ALGORITHM
接受三个值:MERGE
、TEMPTABLE
或 UNDEFINED
。
对于
MERGE
,会合并引用视图的语句的文本和视图定义,以便视图定义的某些部分替换语句的相应部分。对于
TEMPTABLE
,会将视图的结果检索到一个临时表中,然后使用该表执行语句。对于
UNDEFINED
,MySQL 会选择要使用的算法。如果可能,它更喜欢MERGE
而不是TEMPTABLE
,因为MERGE
通常效率更高,而且如果使用临时表,则视图不可更新。如果没有
ALGORITHM
子句,则默认算法由optimizer_switch
系统变量的derived_merge
标志的值确定。有关其他讨论,请参阅 第 10.2.2.4 节,“使用合并或物化优化派生表、视图引用和公用表表达式”。
明确指定 TEMPTABLE
的一个原因是,可以在创建临时表之后、使用它完成语句处理之前释放底层表上的锁。这可能会导致比 MERGE
算法更快的锁释放,以便使用该视图的其他客户端不会被阻塞那么长时间。
视图算法可能是 UNDEFINED
,原因有三
CREATE VIEW
语句中不存在ALGORITHM
子句。CREATE VIEW
语句具有显式ALGORITHM = UNDEFINED
子句。为只能使用临时表处理的视图指定了
ALGORITHM = MERGE
。在这种情况下,MySQL 会生成警告并将算法设置为UNDEFINED
。
如前所述,MERGE
的处理方式是将视图定义的相应部分合并到引用该视图的语句中。以下示例简要说明了 MERGE
算法的工作原理。这些示例假设有一个视图 v_merge
,其定义如下
CREATE ALGORITHM = MERGE VIEW v_merge (vc1, vc2) AS
SELECT c1, c2 FROM t WHERE c3 > 100;
示例 1:假设我们发出以下语句
SELECT * FROM v_merge;
MySQL 处理该语句的方式如下
v_merge
变为t
*
变为vc1, vc2
,这对应于c1, c2
添加视图
WHERE
子句
要执行的结果语句变为
SELECT c1, c2 FROM t WHERE c3 > 100;
示例 2:假设我们发出以下语句
SELECT * FROM v_merge WHERE vc1 < 100;
此语句的处理方式与前一个语句类似,只是 vc1 < 100
变为 c1 < 100
,并且使用 AND
连接词(并添加括号以确保子句的各个部分以正确的优先级执行)将视图 WHERE
子句添加到语句 WHERE
子句中。要执行的结果语句变为
SELECT c1, c2 FROM t WHERE (c3 > 100) AND (c1 < 100);
实际上,要执行的语句具有以下形式的 WHERE
子句
WHERE (select WHERE) AND (view WHERE)
如果无法使用 MERGE
算法,则必须改用临时表。阻止合并的结构与阻止派生表和公用表表达式中合并的结构相同。例如子查询中的 SELECT DISTINCT
或 LIMIT
。有关详细信息,请参阅 第 10.2.2.4 节,“使用合并或物化优化派生表、视图引用和公用表表达式”。