23.5.2 视图处理算法
CREATE VIEW或ALTER VIEW的可选ALGORITHM
子句是标准 SQL 的 MySQL 扩展。它影响 MySQL 处理视图的方式。 ALGORITHM
采用三个值:MERGE
,TEMPTABLE
或UNDEFINED
。
-
对于
MERGE
,引用视图的语句文本和视图定义将合并,以使视图定义的某些部分替换该语句的相应部分。 -
对于
TEMPTABLE
,视图的结果被检索到临时 table 中,然后该 table 用于执行该语句。 -
对于
UNDEFINED
,MySQL 选择使用哪种算法。如果可能的话,它更喜欢MERGE
而不是TEMPTABLE
,因为MERGE
通常更有效,并且如果使用临时 table,则视图不可更新。 -
如果不存在
ALGORITHM
子句,则UNDEFINED
是 MySQL 5.7.6 之前的默认算法。从 5.7.6 开始,默认算法由optimizer_switch系统变量的derived_merge
标志的值确定。有关其他讨论,请参见第 8.2.2.4 节“通过合并或实现来优化派生 table 和视图引用”。
明确指定TEMPTABLE
的原因是,可以在创建临时 table 之后且在用于完成对语句的处理之前在基础 table 上释放锁。与MERGE
算法相比,这可能会导致更快的锁定释放,因此不会长时间阻塞使用该视图的其他 Client 端。
出于以下三个原因,视图算法可以为UNDEFINED
:
-
CREATE VIEW语句中没有
ALGORITHM
子句。 -
CREATE VIEW语句具有显式的
ALGORITHM = UNDEFINED
子句。 -
为只能使用临时 table 处理的视图指定
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
且将视图WHERE
子句使用AND连接词添加到语句WHERE
子句(并添加括号以确保该子句的各个部分以正确的优先级执行) 。要执行的结果语句变为:
SELECT c1, c2 FROM t WHERE (c3 > 100) AND (c1 < 100);
实际上,要执行的语句具有以下形式的WHERE
子句:
WHERE (select WHERE) AND (view WHERE)
如果无法使用MERGE
算法,则必须使用临时 table。防止合并的构造与防止在派生 table 中进行合并的构造相同。示例是子查询中的SELECT DISTINCT
或LIMIT
。有关详细信息,请参见第 8.2.2.4 节“通过合并或实现来优化派生 table 和视图引用”。