何时在 MySQL 中使用视图?

Dav*_*uer 65 mysql optimization view

从多个连接创建表以用于分析时,何时首选使用视图而不是创建新表?

我更喜欢使用视图的一个原因是我们的管理员在 Ruby 中开发了数据库模式,而我对 Ruby 并不熟悉。我可以请求创建表,但需要一个额外的步骤,我希望在开发/测试新连接时有更大的灵活性。

我开始使用关于 SO 相关问题的答案的视图(何时使用 R,何时使用 SQL)。得票最多的答案开始于“在 SQL 中进行数据操作,直到数据位于单个表中,然后在 R 中进行其余的操作”。

我已经开始使用视图,但我遇到了一些视图问题:

  1. 查询要慢得多
  2. 视图不会从生产环境转储到我用于分析的备份数据库。

视图是否适合这种用途?如果是这样,我应该期待性能损失吗?有没有办法加快对视图的查询?

Der*_*ney 49

MySQL 中的视图使用两种不同算法之一处理:MERGETEMPTABLE. MERGE只是具有适当别名的查询扩展。TEMPTABLE就像听起来一样,视图在运行 WHERE 子句之前将结果放入一个临时表中,并且上面没有索引。

“第三个”选项是UNDEFINED,它告诉 MySQL 选择合适的算法。MySQL会尝试使用,MERGE因为它更高效。主要警告:

如果无法使用 MERGE 算法,则必须改用临时表。如果视图包含以下任何结构,则不能使用 MERGE:

  • 聚合函数(SUM()、MIN()、MAX()、COUNT() 等)

  • 清楚的

  • 通过...分组

  • 限制

  • 联合或联合所有

  • 选择列表中的子查询

  • 仅指字面值(在这种情况下,没有基础表)

[源代码]

我冒昧地猜测您的 VIEWS 需要 TEMPTABLE 算法,从而导致性能问题。

这是一篇关于 MySQL 中视图性能的非常古老的博客文章,它似乎并没有变得更好。

然而,关于这个不包含索引的临时表(导致全表扫描)的问题,在隧道的尽头可能会有一些线索。在5.6 中

对于 FROM 子句中的子查询需要物化的情况,优化器可以通过向物化表添加索引来加快对结果的访问。... 添加索引后,优化器可以将物化派生表与普通带有索引的表一样对待,并从生成的索引中获得类似的好处。与没有索引的查询执行成本相比,索引创建的开销可以忽略不计。

正如@ypercube 指出的那样,MariaDB 5.3 增加了相同的优化。这篇文章对这个过程有一个有趣的概述:

应用优化后,派生表无法合并到其父 SELECT 中,这在派生表不符合可合并 VIEW 的条件时发生


Rai*_*lla 17

视图是安全工具。您不希望特定用户或应用程序知道您的数据表的位置,您提供了一个仅包含它需要的列的视图。

请记住,视图总是会降低性能,类似的查询应该是存储过程和函数,而不是视图。

要进行查询调优,请始终遵循最佳实践,避免在 WHERE 子句中使用函数,创建索引以加快选择速度,但不要滥用索引降低插入、更新和删除的性能。

有很好的文档可以帮助您:http : //www.toadworld.com/LinkClick.aspx?fileticket= 3qbwCnzY/ 0A=&tabid=234

  • 我不同意视图是(仅)安全工具。它们可以以这种方式使用,但我们使用它们来消除我们的报表开发人员定期使用的查询中的复杂性。 (7认同)
  • @JHFB:我同意你的看法,但也许这只是它在 MySQL 中的工作方式,听起来似乎会导致严重的性能损失? (2认同)
  • @RainierMorilla 视图会降低性能!?? (2认同)