パフォーマンスに関連するすべての質問と同様に、答えは「状況によって異なります」です。 RLSは、ポリシー関数をWHERE句として適用する外部クエリで制御されたクエリをラップすることによって機能します...
select /*+ rls query */ * from (
select /*+ your query */ ... from t23
where whatever = 42 )
where rls_policy.function_t23 = 'true'
したがって、パフォーマンスへの影響は、関数の内容に完全に依存します。
これらを行う通常の方法は、コンテキスト名前空間を使用することです。これらは、SYS_CONTEXT()関数を介してアクセスされるセッションメモリの事前定義された領域です。そのため、コンテキストから保存された値を取得するコストはごくわずかです。また、通常はセッションごとに1回名前空間にデータを入力するため(たとえば、ログオン後のトリガーまたは同様の接続フックによって)、クエリあたりの全体的なコストはごくわずかです。名前空間を更新する方法はいくつかあり、パフォーマンスに影響を与える可能性がありますが、全体的なスキームでは簡単です(この他の回答を参照してください 。
したがって、パフォーマンスへの影響は、関数が実際に何をするかによって異なります。それはあなたの実際の方針の考察に私達をもたらします:
良いニュースは実行です そのような機能のそれ自体が費用がかかる可能性は低いです。悪いニュースは、パフォーマンスがまだTeh Suckである可能性があることです!とにかく、過去の記録に対するライブ記録の比率が好ましくない場合。おそらく、すべてのレコードを取得してから、履歴レコードを除外することになります。オプティマイザーはRLS述語をメインクエリにプッシュする可能性がありますが、RLSの動作方法のため、可能性は低いと思います。ポリシーの基準を一般的な視線にさらすことを回避します(これにより、RLS操作のデバッグが実際のPITNになります)。
あなたのユーザーはあなたの貧弱な設計決定の代償を払うでしょう。古いレコードを保存し、実際のテーブルにライブデータのみを保持するには、ジャーナルテーブルまたは履歴テーブルを用意することをお勧めします。過去の記録を実際の記録と一緒に保持することが、拡張可能なソリューションになることはめったにありません。
DBMS_RLSにはEnterpriseEditionライセンスが必要です。