Sql 如何根据用户对具有特定条件的特定记录的权限高效筛选大量记录?

Sql 如何根据用户对具有特定条件的特定记录的权限高效筛选大量记录?,sql,architecture,data-access-layer,Sql,Architecture,Data Access Layer,我是一个基于Java的旧式货运铁路托运单会计系统的维护人员。检索要在其网站上显示的寄售通知列表时存在严重的性能问题 我无法发布整个查询,但以下是一些统计数据,以提供总体思路: 它有17个左连接 它有一个巨大的where子句,包含5个或多个组,用于确定是否允许用户访问与记录(发货人、收货人、承运人、付款人、监管人)相关的记录,并检查用户访问与特定火车站相关记录的权限 OR组中的每个组平均有两个exists()检查子查询与记录相关的一些数据,并检查电台权限 当扩展为人类可读时,查询大约有200行长

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

我无法发布整个查询,但以下是一些统计数据,以提供总体思路:

  • 它有17个左连接
  • 它有一个巨大的
    where
    子句,包含5个或多个组,用于确定是否允许用户访问与记录(发货人、收货人、承运人、付款人、监管人)相关的记录,并检查用户访问与特定火车站相关记录的权限
  • OR组中的每个组平均有两个
    exists()
    检查子查询与记录相关的一些数据,并检查电台权限
  • 当扩展为人类可读时,查询大约有200行长
基本上,每个记录对当前登录用户的可用性取决于以下因素: -用户的公司 -承运人的公司、收货人、发货人、每个特定托运单的付款人 -每个托运单都有多个路线区段,每个区段都有自己的承运人和付款人,因此需要进一步的访问控制条件,以使这些记录对用户可见 -每个托运单和每个路线区段都有起点站和终点站,只有当用户被允许访问其中任何一个站(使用简单的关系表)时,才允许用户查看记录

数据库中大约有200万条寄售通知单记录,客户抱怨加载一个包含20条记录的页面花费的时间太长

不幸的是,在将最终查询传递给RDBMS(具体来说是Oracle 11g)之前,不可能对其进行优化,因为系统具有复杂的体系结构和一个自制ORM工具,并且最终查询至少在三个不同的位置进行组装,这三个位置负责收集要选择的字段、收集连接、,添加在UI中选择的条件,最后添加此问题的原因-权限相关筛选器

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

我担心缓存解决方案在这种情况下不会非常有效,因为数据经常更改,缓存大约每分钟都会被覆盖一次。此外,由于具有单独的权限,每个用户都应该拥有自己的缓存,这些缓存必须进行维护


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

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

首先,您需要获取查询的执行计划。没有它,要想知道什么可以改进就不那么容易了。如果不是因为你的紧迫感,这听起来是个不错的挑战

你说这个查询有17个左连接。这是否意味着查询中只有一个主表?如果是这样,那么这就是我要优化的第一部分。关键的方面是尽可能减少ROWID对
表的访问。典型的解决方案是添加定制良好的索引,以尽可能缩小该表上的
索引范围扫描
,从而减少堆获取

然后,在浏览其余[outer]表时(可能使用
嵌套循环
),您可以尝试将其中一些条件具体化为可以使用的简单0/1标志,而不是整个条件

另外,如果你只需要20行,我希望这会非常快。。。只要查询是正确的管道化的。如果在你的情况下,这需要很长时间,那么可能不是这样。您是否根据阻止流水线的特定条件进行排序/聚合/窗口化?如果只需要20行,这个条件可能是索引的最重要因素

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

好的,好的解决方案确实需要仔细研究执行计划。如果你仍然是游戏,张贴它,我可以看看它