【发布时间】:2011-11-19 02:00:17
【问题描述】:
假设我有一个表 A,从该表创建一个视图 V。
然后我从V做几个查询,不知道每次查询都会重新构造V吗?或者它只会被构建 1 次,并被 DBMS 保存在内存中的某个位置以供下一次查询(我认为这类似于从表中查询)?
【问题讨论】:
-
stackoverflow.com/questions/2054980/… 检查答案,他们更好地解释了为什么应该使用视图而不是实际查询。
假设我有一个表 A,从该表创建一个视图 V。
然后我从V做几个查询,不知道每次查询都会重新构造V吗?或者它只会被构建 1 次,并被 DBMS 保存在内存中的某个位置以供下一次查询(我认为这类似于从表中查询)?
【问题讨论】:
MySQL 中的视图并不是事实上的缓存解决方案。
每次查询这些基表的视图时,MySQL 都会针对基表运行查询。查询的结果不会存储在视图中。
因此,无需像在 Oracle Microsoft SQL Server 中使用物化视图那样“刷新”视图。每次查询视图时,甚至 MySQL 视图定义中的 SQL 都会重新计算。
如果您需要 MySQL 中的物化视图之类的东西,FlexViews 可能会有所帮助。这会将查询的结果存储在普通的基表中,然后监视记录在 MySQL 二进制日志中的更改,将相关更改应用于基表。这个工具可能非常有用,但它有一些注意事项:
【讨论】:
Mysql 视图不支持索引。 (就像在 Oracle 中,您可以在 Oracle 视图中创建索引)但是 mysql 视图在使用合并算法创建时可以使用基础表中的索引。
如果您必须使用视图,请调整您的 JOIN BUFFER。
使用,类似这样的东西
设置全局join_buffer_size=314572800;
请分析更改缓冲区大小之前和之后的差异。 我看到增加连接缓冲区后,视图查询的执行时间(以毫秒为单位)与相同大小的表的执行时间相同。
【讨论】:
MERGE算法并且没有派生列,MySQL视图将使用索引。
一般来说,不会。 V 是在查询请求时计算的一组临时行。因为您可以在从视图查询时应用额外的 WHERE 和 ORDER BY 条件,所以可以想象,针对同一视图的两个查询的执行计划可能完全不同。数据库通常不能重用针对视图的上一个查询的结果来满足针对该视图的下一个查询。
也就是说,在某些引擎中存在一种相对较新的技术,称为物化视图。我自己从未使用过它们,但我的理解是这些视图是根据对基础表进行的更新预先计算的。因此,使用物化视图确实可以提高 SELECT 性能,但代价是降低 INSERT、UPDATE 和 DELETE 性能。
您还应该知道,多列索引可用于预先计算涉及单个表的某些选择和排序顺序。如果您对可以使用复合索引满足的表发出查询(查询只需要索引中的列,并且排序顺序与索引匹配),那么永远不需要读取表本身,只需要读取索引。
【讨论】:
根据 Pinal Dave,a view must be refreshed in order to reflect changes made to its referenced table(s)。我不确定这是否会使简单的 1 表查询视图比直接查询表更有效(它可能不会),但我认为这意味着包含复杂连接和子查询的视图可能比它们的非- 查看同行。
Pinal Dave 对其他 limitations of SQL views(或功能,如果您愿意)有更多话要说。也许你可以在那里学到一些有用的东西。
【讨论】: