23.5.2 视图处理算法

CREATE VIEWALTER VIEW的可选ALGORITHM子句是标准 SQL 的 MySQL 扩展。它影响 MySQL 处理视图的方式。 ALGORITHM采用三个值:MERGETEMPTABLEUNDEFINED

  • 对于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 DISTINCTLIMIT。有关详细信息,请参见第 8.2.2.4 节“通过合并或实现来优化派生 table 和视图引用”