如何根据具有特定条件的特定记录的用户权限有效过滤大量记录?

问题描述 投票:1回答:1

我是一家传统的基于Java的货运铁路托运票据会计系统的维护人员。检索要在其网站上显示的寄售单列表存在严重的性能问题。

我无法发布整个查询,但这里有一些统计数据可以提供一般性的想法:

  • 它有17个左连接
  • 它有一个巨大的where条款,带有5个OR组,以确定是否允许用户访问记录,因为与记录(发货人,收货人,承运人,付款人,主管)有特定关系,并检查用户是否允许访问与记录相关的记录。一个特定的火车站
  • 每个OR组平均有两个exists()检查子查询与记录相关的一些数据,并检查站点权限
  • 当扩展为人类可读时,查询大约200行

基本上,每个记录对当前登录用户的可用性取决于以下因素: - 用户公司 - 承运人公司,收货人,发货人,每个特定托运单的付款人 - 每个托运单都有多个路径部分并且每个部分都有自己的运营商和付款人,因此需要进一步的访问控制条件以使这些记录对用户可见 - 每个运单和每个路段都有原始站和目的站,并且只有当用户被允许时才允许用户查看记录。已被授予访问任何这些站的权限(使用简单的关系表)。

数据库中有大约200万份托运单记录,客户抱怨加载包含20条记录的页面需要很长时间。

遗憾的是,在将最终查询传递给RDBMS(特定于Oracle 11g)之前无法对其进行优化,因为系统具有复杂的体系结构和自制的ORM工具,并且最终查询至少在三个不同的组合中进行组装负责收集字段以进行选择,联接集合,添加在UI中选择的条件以及最终解决此问题的原因的地方 - 与权限相关的过滤器。

我不会说最后的查询非常复杂;相反,它本质上很简单,但它只是巨大的。

在这种情况下,我担心缓存解决方案不会非常有效,因为数据经常变化,并且每隔一分钟就会覆盖缓存。此外,由于个人权限,每个用户都应该拥有必须维护的自己的缓存。

除了通常的建议 - 处理索引和尽可能优化每个子查询 - 还有其他任何众所周知的解决方案,用于根据复杂的权限规则过滤大量记录吗?

sql architecture data-access-layer
1个回答
1
投票

只是我的两分钱,因为我看不到其他答案。

首先,您需要获取查询的执行计划。没有它,了解可以改进的东西并不容易。如果不是你的紧迫感,这听起来是一个很好的挑战。

好吧,你说查询有17个左连接。这是否意味着查询中有一个主表?如果是这样,那么这就是我要优化的第一部分。关键方面是在该表上尽可能减少TABLE ACCESS BY ROWID操作。典型的解决方案是添加经过良好定制的索引,以尽可能地在该表上缩小INDEX RANGE SCAN,从而减少堆取。

然后,当导航其余的[外部]表(大概使用NESTED LOOPS)时,您可以尝试将其中一些条件实现为可以使用的简单0/1标志,而不是整个条件。

此外,如果你只需要20行,我希望它非常快......只要查询是正确的流水线。如果在你的情况下它花了太长时间,那么情况可能并非如此。您是否按某些阻止流水线操作的特定条件进行排序/聚合/窗口化?如果您只需要20行,这种情况可能是索引的最重要因素。

最后,您可以尝试使用“覆盖索引”来避免堆提取。这可以真正提高您的查询性能,但我会把它作为最后的手段,因为它们有它们的缺点。

那么,一个好的解决方案真的需要好好看一下执行计划。如果你仍然是游戏,发布它,我可以看看它。

© www.soinside.com 2019 - 2024. All rights reserved.