如果我们使用Oracle行级别安全性(RLS)隐藏一些记录 - 是否有任何性能影响 - 它会减慢我的SQL查询吗? Oracle Package for this is:DBMS_RLS。
我打算在某些表中添加:IS_HISTORICAL = T / F.然后使用RLS隐藏值为IS_HISTORICAL = T的记录。
我们在应用程序中使用的SQL查询非常复杂,包括内部/外部联接,子查询,相关子查询等。
在200多个表中,其中约有50个表格将应用此RLS策略(以隐藏IS_HISTORICAL = T的记录)。 150个表中的其余表是这50个表的子表,因此RLS隐含在它们之上。
任何许可证含义?
感谢。
答案 0 :(得分:2)
“是否有任何性能影响 - 它会减慢我的SQL速度 查询? “
与所有与表现相关的问题一样,答案是“它取决于”。 RLS的工作原理是将受控查询包装在外部查询中,该查询将策略函数应用为WHERE子句...
select /*+ rls query */ * from (
select /*+ your query */ ... from t23
where whatever = 42 )
where rls_policy.function_t23 = 'true'
因此,性能影响完全取决于功能中的内容。
执行这些操作的常规方法是使用上下文命名空间。这些是通过SYS_CONTEXT()函数访问的会话内存的预定义区域。因此,从上下文中检索存储值的成本可以忽略不计。正如我们通常每个会话填充命名空间一次 - 比如通过登录后触发器或类似的连接挂钩 - 每个查询的总体成本是微不足道的。刷新命名空间有不同的方法,这可能会影响性能,但这些方法在整个方案中都是微不足道的(see this other answer)。
因此,性能影响取决于您的功能实际执行的内容。这让我们考虑到您的实际政策:
“此RLS政策(通过IS_HISTORICAL = T隐藏记录)”
好消息是这种功能的执行本身不太可能成本高昂。坏消息是表现可能仍然是Teh Suck!无论如何,如果实时记录与历史记录的比例是不利的。您可能最终会检索所有记录,然后过滤掉历史记录。优化器可能会将RLS谓词推入主查询中,但我认为这不太可能是因为RLS的工作方式:它避免了将策略的标准暴露给一般注视(这使得调试RLS操作成为真正的PITN)。
您的用户将为您糟糕的设计决定付出代价。使用日志记录表或历史记录表来存储旧记录并仅在实际表中保留实时数据要好得多。保留历史记录和实时记录很少是一种可扩展的解决方案。
“任何许可证含义?”
DBMS_RLS需要企业版许可证。