MySQL5.0版本以后开始引入视图。视图本身是一个虚拟表,不存放任何数据。在使用SQL语句访问视图的时候,它返回的数据是MySQL、

从其他表中生成的。视图和表是在同一个命名空间,MySQL在很多地方对于视图和表时同样对待的。不过视图和表也有不同,例如,不能对视图创建触发器,也不能使用drop taable命令删除视图。

在MySQL官方手册中对如何创建和使用视图有详细的介绍,下面主要介绍视图是如何实现的,以及优化器如何处理视图,通过了解这些,希望可以让大家在使用视图的时候获得更高的性能。:

create view Oceania as 
select * from country where continent = 'Oceania' 
with check option;

实现视图最简单的方式是将select语句的结果存放到临时表中。当需要访问视图的时候,直接访问这个临时表就可以了:

select code,name from Oceania where name = 'china'

下面是使用临时表来模拟视图的方法:

create temporary table tmp_123 as select * from country where continent = 'Oceania';
select code,name from tmp_123 where name = 'china';

这样做会有明显的性能问题,优化器也很难优化在这个临时表上的查询。实现视图更好的方式是,重写含有视图的查询,将视图的定义sql直接包含进查询的sql中,下面是将视图定义的sql合并进查询后的例子:

select code,name from country where continent = 'Oceania' and name = 'china'

MySQL可以使用者两种八法中的任何一种来处理视图。这两种算法分别称为合并算法和临时表算法,如果可能会尽可能的使用合并算法。MySQL甚至可以嵌套的定义视图,也就是在一个视图上在定义另一个视图。可以在explain extended之后使用show warnings来查看使用视图的查询重写后的结果。

如果采用临时表算法实现的视图,explain中会显示为派生表。

mysql 视图 可以做纵横转换吗 mysql视图能提高性能吗_新视图

如果视图中包含group by、distinct、任何聚合函数、union、子查询等,只要无法在原表记录和视图记录中简历一一映射的场景中,MySQL都将使用临时表算法来实现视图。上面例句的可能不全,而且这些规则在以后的版本中也可能会改变。如果想确定使用的是哪种算法实现的可以使用explain命令查询:

explain select * from view_name

select_type为derived,说明视图采用临时表算法实现的。不过需要注意:如果产生的底层派生表很大,那么执行explain可能会非常慢。因为在MySQL5.5以前,explain是需要实际执行并产生该派生表的。

视图的实现算法是视图本身的属性,和作用在视图上的查询语句无关。例如,可以为一个机遇简单查询的视图指定使用临时表算法:

create algorithm = temptable view v1 as select * from test_user

实现该视图的sql本身并不需要临时表,但机遇该视图无论执行什么样的查询,视图都会生成一个临时表。

1 可更新视图

可更新视图是指可以通过更新这个视图来更新视图设计的相关表。只要指定了合适的条件,就可以更新、删除甚至想视图中写入数据:

update oceanis set population = population * 1.1 where name = 'china';

如果视图中包含了group by、union、聚合函数以及其他一些特殊情况,就不嗯呢该被更新了。更新视图的查询也可以是一个关联语句,但是有一个限制,被更新的列必须来自同一个表。另外,所有使用临时表算法实现的视图都无法被更新。

某些关系数据库允许在视图上简历inserad of触发器,通过触发器可以精确控制在修改视图数据时做些什么,不过MySQL不支持

2 视图对性能的影响

多数人认为视图不能提升性能,实际上在MySQL中某些情况下视图可以提升性能。而且视图还可以和其他提升性能的方式叠加使用。例如重构schema的时候,使得在修改视图底层表结构的时候,应用代码还可能继续不报错的运行。

可以使用视图实现基于列的权限控制,却不需要真正在系统中创建列权限,因此没有额外的开销。

3 视图的限制

① 不支持物化视图

② 不支持创建索引

③ 视图不会保存视图定义的原始sql语句

由于视图实际使用场景不是很多,所以细节不在描述。外键索引基本已经无人使用了吧,所以也不写了。