提高视图的性能

Posted

技术标签:

【中文标题】提高视图的性能【英文标题】:Improving performance of views 【发布时间】:2012-01-31 01:04:01 【问题描述】:

我有一个管理记录级权限的视图。为此,我们将其称为“AuthorityView”。它通过查看基础表、实际的“数据”、“记录权限”表和“用户组”表来工作。

在本例中,我们选择“员工”记录。有一个核心表“EmployeeData”,它包含所有数据,一个“EmployeeRecordAuthority”,它指定哪些用户组对数据有什么访问权限(读、读/写、更新、删除等),以及“用户组”只存储用户所属的组。

该视图使用了一个相当简单的连接,但会处理大量记录(约 100k 员工记录和约 3m 记录权限记录)。最终结果是用户可以查看的记录子集。

我遇到的问题是在没有条件的情况下查询视图非常慢。执行“从 EmployeeAuthorityView 中选择 *”大约需要 6-7 分钟,但是,对其应用“顶部”可以使其按预期执行。 “Select top 10000000 * from EmployeeAuthorityView”只需几秒钟。

表之间存在所有相关索引,并且已重建。

什么可能导致查询速度变慢?为什么即使数量远大于表中的记录数,使用指定的“顶部”限制查询也会更快?

提前致谢。

【问题讨论】:

这是 Oracle、mysql、SQL Server 还是其他 RDBMS? 【参考方案1】:

性能差异可能是因为数据库查询优化器用于检索数据的策略不同。

确切的原因取决于您使用的是哪个 DBMS,以及它的查询优化器是如何编写的,但问题出在“没有条件的视图”的概念上,类似于以下内容。

您的 EmployeeAuthorityView 看起来像是 Data、RecordAuthority 和 UserGroups 表的连接。因此,在没有任何过滤条件的情况下,视图本身定义了一个理论集,即这些表的乘积(外连接)。该理论集包含 100,000 x 3,000,000 x U 记录(U 是您的 UserGroups 表的大小)。一旦你应用了一些选择标准,理论集的大小就会大大减少,但没有标准它是数万亿条记录(假设你的 UserGroups 表有超过 3 行)。

DBMS 需要实例化这个理论集的多少条记录,才能为您提供一个已满的缓冲区?查询优化器考虑了多种策略,包括(策略 A)在将第一个缓冲区满返回到您的应用程序之前创建所有 300U 亿条记录,(策略 B)仅根据需要创建记录,并在您的应用程序中返回一个已满的缓冲区有那么多。除其他外,影响该选择的因素包括“需要以什么顺序将记录返回到您的应用程序”。使用“顶部”限制会导致订单的定义不同,在这种情况下,它会选择策略 B 之类的东西。

【讨论】:

以上是关于提高视图的性能的主要内容,如果未能解决你的问题,请参考以下文章

视图的索引字段是不是会提高 MySQL 的性能?

使用视图提高查询性能

提高视图的性能

提高 Oracle 视图的性能

基于函数的索引没有提高查询性能

如何提高表视图中的 UILabel 性能?