当前位置:首页 > 芯闻号 > 充电吧
[导读]视图是MySQL 5.0中增加的三大新功能之一(另外两个是存储过程与触发器),也是一般稍微“高级”一点的数据库所必需要有的功能。MySQL在定义视图上没什么限制,基本上所有的查询都可定义为视图,并且也

视图是MySQL 5.0中增加的三大新功能之一(另外两个是存储过程与触发器),也是一般稍微“高级”一点的数据库所必需要有的功能。MySQL在定义视图上没什么限制,基本上所有的查询都可定义为视图,并且也支持可更新视图(当然只有在视图和行列与基础表的行列之间存在一一对应关系时才能更新),因此从功能上说MySQL的视图功能已经很完善了。


然而若要在应用中使用视图,还需要了解处理视图时的性能,而MySQL在这方面问题是比较大的,需要特别注意。首先要知道MySQL在处理视图时有两种算法,分别称为MERGE和TEMPTABLE。在执行"CREATE VIEW"语句时可以指定使用哪种算法。所谓MERGE是指在处理涉及到视图的操作时,将对视图的操作根据视图的定义进行展开,有点类似于C语言中的宏展开。比如设有以下的表(类似于博客中的评论):
CREATE TABLE `comment` (
  `id` int(11) NOT NULL,
  `user_id` int(11) default NULL,
  `content` varchar(255) default NULL,
  PRIMARY KEY  (`id`),
  KEY `idx_comment_uid` (`user_id`)
) ENGINE=InnoDB;
假设user_id < 10000的用户为VIP用户,我们可以这样创建一个视图来表示VIP用户的评论:
CREATE VIEW vip_comment AS SELECT * FROM comment WHERE user_id < 10000;
这时我们在操作vip_comment视图时使用的就是MERGE算法。如:
mysql > EXPLAIN EXTENDED SELECT count(*) FROM vip_comment WHERE user_id < 0;
+----+-------------+---------+-------+-----------------+-----------------+---------+------+------+--------------------------+
| id | select_type | table   | type  | possible_keys   | key             | key_len | ref  | rows | Extra                    |
+----+-------------+---------+-------+-----------------+-----------------+---------+------+------+--------------------------+
|  1 | SIMPLE      | comment | range | idx_comment_uid | idx_comment_uid | 5       | NULL |   10 | Using where; Using index |
+----+-------------+---------+-------+-----------------+-----------------+---------+------+------+--------------------------+
mysql> show warnings;
+-------+------+---------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message                                                                                                                               |
+-------+------+---------------------------------------------------------------------------------------------------------------------------------------+
| Note  | 1003 | select count(0) AS `count(*)` from `test`.`comment` where ((`test`.`comment`.`user_id` < 0) and (`test`.`comment`.`user_id` < 10000)) | 
+-------+------+---------------------------------------------------------------------------------------------------------------------------------------+
可以看到,对vip_comment的操作已经被扩展为对comment表的操作。

一般来说在能够使用MERGE算法的时候MySQL处理视图上没什么性能问题,但并非在任何时候都能使用MERGE算法。事实上,只要视图的定义稍稍有点复杂,MySQL就没办法使用MERGE算法了。准确的说,只要视图定义中使用了以下SQL构造块就无法使用MERGE算法:

聚集函数DISTINCTGROUP BYHAVING集合操作(在MySQL中只有UNION, UNION ALL,没有EXCEPT和INTERSECT)子查询确实,在视图定义比较复杂的情况下,要对视图操作进行有效的优化是非常困难的。因此在这个时候,MySQL使用了一种以不变应万变的方法,即先执行视图定义,将其结果使用临时表保存起来,这样后续对视图的操作就转化为对临时表的操作。不能不说从单从软件设计的角度看,这样的方法非常的优雅,然而从性能角度,这一方法也是非常的差。

比如我们希望使用如下的视图来表示每个用户的评论数,即:
CREATE VIEW comment_count AS SELECT user_id, count(*) AS count FROM comment GROUP BY user_id;
使用这个视图的时候,我们可能心里有个小算盘。目前我们先用这个视图顶着,如果性能确实有问题,那我们就再来搞一张comment_count的表,其中就记下来每个用户的评论数。而我们现在先用这个视图是为了将来要是改的话会方便点(这也是视图--即教科书中所谓的外模式--这个东西存在的主要原因之一,另一主要原因是便于权限控制)。但是遇到了MySQL这个蠢货,我们的算盘铁定会失败。
我们来看一下指定user_id从comment_count选取记录时的执行策略:
mysql> explain select count(*) from comment_count where user_id = 90;
+----+-------------+------------+-------+---------------+-----------------+---------+------+--------+-------------+
| id | select_type | table      | type  | possible_keys | key             | key_len | ref  | rows   | Extra       |
+----+-------------+------------+-------+---------------+-----------------+---------+------+--------+-------------+
|  1 | PRIMARY     |

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

来源:https://juejin.cn/post/6860252224930070536| 背景日志是 mysql 数据库的重要组成部分,记录着数据库运行期间各种状态信息。mysql日志主要包括错误日志、查询日志、慢查...

关键字: mysql

mysql的一行记录,最终肯定是存储在磁盘上,也就是肉眼可见的文件上,今天我们的目标很简单,就是看看它到底是怎么存的。当然还有一个更重要的目标,就是以这个为引子,带大家完全通过一手资料,来揭秘这个问题的答案。所以大家阅读...

关键字: mysql

跟着官方文档 源码 源文件三件套自己探索

关键字: mysql 存储

什么Mysql的事务?事务的四大特性?事务带来的什么问题?你详细了解过MVCC吗?它是怎么工作的?

关键字: mysql 嵌入式

想进大厂,mysql不会那可不行,来接受mysql面试挑战吧,看看你能坚持到哪里?

关键字: mysql 嵌入式

最近,在开发一个分库分表中间件,由于功能需求,需要分析MySQL协议,发现网上对于MySQL协议分析的文章大部分都过时了,原因是分析的MySQL版本太低了。怎么办?于是乎,我便硬着头皮开始啃MySQL源码,经过两个多月的...

关键字: mysql 嵌入式

想进大厂,Mysql不会那可不行,来接受Mysql面试挑战吧,看看你能坚持到哪里?

关键字: mysql 嵌入式

Explain被称为执行计划,在语句之前增加explain关键字,MySQL会在查询上设置一个标记,模拟MySQL优化器来执行SQL语句,执行查询时,会返回执行计划的信息,并不执行这条SQL。

关键字: mysql 嵌入式

什么是事务?事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。

关键字: mysql 嵌入式

此文不会事无巨细的从select的用法开始讲解mysql,主要针对的是开发人员需要知道的一些MySQL的知识点,主要包括索引、事务、优化等方面,以在面试中高频的问句形式给出答案。

关键字: mysql 嵌入式
关闭
关闭