2019独角兽企业重金招聘Python工程师标准>>>
视图可选的ALGORITHM子句
测试版本:
percona server 5.6.19-67.0-log Percona Server (GPL), Release 67.0, Revision 618
该选项是Mysql扩展的SQL标准,影响mysql怎样处理视图,可以有三个值:MERGE,TEMPTABLE,UNDEFINED,默认是UNDEFINED。
总结:
视图能被mysql进行重写优化,需要满足一些条件,同时在定义时,不能使用TEMPTABLE算法
MERGE:
合并视图定义到相应的查询语句(视图重写)。
TEMPTABLE:
从视图检索的结果集存放到临时表,然后执行查询语句(影响视图重写)。
UNDEFINED:
mysql选择使用哪个算法,优先MERGE,通常更有效,如果使用临时表,视图不能更新,但是使用TEMPTABLE可以提前释放对基表的锁
如:
创建基本表:
Create Table: CREATE TABLE `t` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
使用MERGE算法创建简单视图:
root@[test1] 12:29:50>CREATE ALGORITHM = MERGE VIEW v_merge (vc1, vc2) AS SELECT c1, c2 FROM t WHERE c3 > 100;
Query OK, 0 rows affected (0.00 sec)
root@[test1] 12:30:00>explain extended SELECT * FROM v_merge;
+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | t | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
查看优化后的语句:视图已经重写为基本表t,并将视图的where条件应用到查询语句
root@[test1] 12:30:21>show warnings;
+-------+------+---------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+---------------------------------------------------------------------------------------------------------------------------+
| Note | 1003 | /* select#1 */ select `test1`.`t`.`c1` AS `vc1`,`test1`.`t`.`c2` AS `vc2` from `test1`.`t` where (`test1`.`t`.`c3` > 100) |
+-------+------+---------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
使用TEMPTABLE算法创建同上面定义的视图:
root@[test1] 12:30:26>CREATE ALGORITHM = TEMPTABLE VIEW v_temptable (vc1, vc2) AS SELECT c1, c2 FROM t WHERE c3 > 100;
Query OK, 0 rows affected (0.00 sec)
查询计划:使用了衍生表,也就是先执行视图定义,然后将结果集用于执行查询语句
root@[test1] 12:31:08>explain extended SELECT * FROM v_temptable;
+----+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | NULL |
| 2 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
查看优化后的语句:视图名没有去掉,没有将简单查询进行重写为对基表的查询
root@[test1] 12:31:17>show warnings;
+-------+------+------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------------------------------------------------------------------------------+
| Note | 1003 | /* select#1 */ select `v_temptable`.`vc1` AS `vc1`,`v_temptable`.`vc2` AS `vc2` from `test1`.`v_temptable` |
+-------+------+------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
使用UNDEFINED的情况:
1、没有使用ALGORITHM子句;
2、使用明确的ALGORITHM=UNDEFINED定义;
3、ALGORITHM=MERGE,如果含有一些特殊结构,Mysql生成一个警告,并设置算法为UNDEFINED;
如果视图包含下面的结构,不能使用MERGE:
1、聚合函数(SUM(),MIN(),MAX(),COUNT()等)
2、DISTINCT;
3、GROUP BY;
4、HAVING
5、LIMIT
6、UNION或UNION ALL
7、子查询在select列
8、参考仅仅文字值,没有潜在表
如:
1、视图包含聚合函数:
root@[test1] 15:22:25>CREATE ALGORITHM = MERGE VIEW v_merge_sum (vc1) AS SELECT sum(c1) FROM t WHERE c3 > 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
查看警告可以得到使用undefined算法,不能使用merge算法
root@[test1] 15:22:41>show warnings;
+---------+------+-------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------------------------------------------+
| Warning | 1354 | View merge algorithm can't be used here for now (assumed undefined algorithm) |
+---------+------+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)
查看视图定义:使用UNDEFINED算法
root@[test1] 14:56:26>show create table v_merge_sum\G;
*************************** 1. row ***************************
View: v_merge_sum
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_merge_sum` AS select sum(`t`.`c1`) AS `vc1` from `t` where (`t`.`c3` > 1)
character_set_client: gbk
collation_connection: gbk_chinese_ci
1 row in set (0.00 sec)
ERROR:
No query specified
对视图进行简单查询:使用了衍生表,但是视图名没有出现
root@[test1] 15:23:05>explain extended select * from v_merge_sum;
+----+-------------+------------+--------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+--------+---------------+------+---------+------+------+----------+-------------+
| 1 | PRIMARY | | system | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
| 2 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | Using where |
+----+-------------+------------+--------+---------------+------+---------+------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
root@[test1] 15:23:17>show warnings;
+-------+------+----------------------------------------------+
| Level | Code | Message |
+-------+------+----------------------------------------------+
| Note | 1003 | /* select#1 */ select '6' AS `vc1` from dual |
+-------+------+----------------------------------------------+
1 row in set (0.00 sec)
2、视图包含distinct:
root@[test1] 15:25:05>CREATE ALGORITHM = MERGE VIEW v_merge_distinct (vc1,vc2) AS SELECT distinct c1,c2 FROM t WHERE c3 > 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
查看警告可以得到使用undefined算法,不能使用merge算法
root@[test1] 15:25:20>show warnings;
+---------+------+-------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------------------------------------------+
| Warning | 1354 | View merge algorithm can't be used here for now (assumed undefined algorithm) |
+---------+------+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)
查询计划:使用了衍生表,视图没有重写
root@[test1] 15:25:24>explain extended select * from v_merge_distinct;
+----+-------------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | NULL |
| 2 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | Using where; Using temporary |
+----+-------------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
2 rows in set, 1 warning (0.00 sec)
root@[test1] 15:26:13>show warnings;
+-------+------+---------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+---------------------------------------------------------------------------------------------------------------------------+
| Note | 1003 | /* select#1 */ select `v_merge_distinct`.`vc1` AS `vc1`,`v_merge_distinct`.`vc2` AS `vc2` from `test1`.`v_merge_distinct` |
+-------+------+---------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
3、视图包含group by子句:不是使用MERGE算法
root@[test1] 15:30:58>CREATE ALGORITHM = MERGE VIEW v_merge_groupby (vc1,vc2) AS SELECT c1,c2 FROM t group by c3;
Query OK, 0 rows affected, 1 warning (0.12 sec)
root@[test1] 15:31:44>show warnings;
+---------+------+-------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------------------------------------------+
| Warning | 1354 | View merge algorithm can't be used here for now (assumed undefined algorithm) |
+---------+------+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)
查看简单查询的查看计划:使用衍生表,使用临时表进行排序,视图没有消除
root@[test1] 15:31:48>explain extended select * from v_merge_groupby;
+----+-------------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | NULL |
| 2 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | Using temporary; Using filesort |
+----+-------------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
2 rows in set, 1 warning (0.00 sec)
root@[test1] 15:33:02>show warnings;
+-------+------+------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------------------------------------------------------------------------------------------+
| Note | 1003 | /* select#1 */ select `v_merge_groupby`.`vc1` AS `vc1`,`v_merge_groupby`.`vc2` AS `vc2` from `test1`.`v_merge_groupby` |
+-------+------+------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
4、视图含limit条件:不能使用MERGE算法
root@[test1] 15:35:02>CREATE ALGORITHM = MERGE VIEW v_merge_limit (vc1,vc2) AS SELECT c1,c2 FROM t where c3>2 limit 10;
Query OK, 0 rows affected, 1 warning (0.00 sec)
root@[test1] 15:35:39>show warnings;
+---------+------+-------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------------------------------------------+
| Warning | 1354 | View merge algorithm can't be used here for now (assumed undefined algorithm) |
+---------+------+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)
简单查询的查询计划:使用衍生表,视图没有重写成基表
root@[test1] 15:35:41>explain extended select * from v_merge_limit;
+----+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | NULL |
| 2 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
root@[test1] 15:35:54>show warnings;
+-------+------+------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------------------------------------------------------------------------------------+
| Note | 1003 | /* select#1 */ select `v_merge_limit`.`vc1` AS `vc1`,`v_merge_limit`.`vc2` AS `vc2` from `test1`.`v_merge_limit` |
+-------+------+------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
5、子查询在目标列:不能使用使用MERGE算法
root@[test1] 15:45:43>CREATE ALGORITHM = MERGE VIEW v_merge_select (vc1,vc2) AS SELECT c1,(select c2 from t where c1=1) FROM t where c3>2;
Query OK, 0 rows affected, 1 warning (0.00 sec)
root@[test1] 15:45:49>show warnings;
+---------+------+-------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------------------------------------------+
| Warning | 1354 | View merge algorithm can't be used here for now (assumed undefined algorithm) |
+---------+------+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)
简单查询的查询计划:使用衍生表,视图没有重写成基表
root@[test1] 15:45:53>explain extended select * from v_merge_select;
+----+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | NULL |
| 2 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | Using where |
| 3 | SUBQUERY | t | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)
root@[test1] 15:46:10>show warnings;
+-------+------+---------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+---------------------------------------------------------------------------------------------------------------------+
| Note | 1003 | /* select#1 */ select `v_merge_select`.`vc1` AS `vc1`,`v_merge_select`.`vc2` AS `vc2` from `test1`.`v_merge_select` |
+-------+------+---------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
6、视图含UNION
root@[test1] 15:52:48>CREATE ALGORITHM = MERGE VIEW v_merge_union AS SELECT c1,c2 FROM t where c3>2 union select b1,b2 from a;
Query OK, 0 rows affected, 1 warning (0.00 sec)
root@[test1] 15:56:11>show warnings;
+---------+------+-------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------------------------------------------+
| Warning | 1354 | View merge algorithm can't be used here for now (assumed undefined algorithm) |
+---------+------+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)
简单查询的查询计划:使用衍生表,视图没有重写成基表
root@[test1] 15:56:15>explain extended select * from v_merge_union;
+----+--------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 6 | 100.00 | NULL |
| 2 | DERIVED | t | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | Using where |
| 3 | UNION | a | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | NULL |
| NULL | UNION RESULT | | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
4 rows in set, 1 warning (0.00 sec)
root@[test1] 15:56:32>show warnings;
+-------+------+--------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+--------------------------------------------------------------------------------------------------------------+
| Note | 1003 | /* select#1 */ select `v_merge_union`.`c1` AS `c1`,`v_merge_union`.`c2` AS `c2` from `test1`.`v_merge_union` |
+-------+------+--------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
来自为知笔记(Wiz)