下面是 3 個表腳本。
CREATE TABLE rls_permission(upn text,is_all boolean ,reference int[]);
CREATE TABLE objects(key serial primary key,status text );
CREATE TABLE object_attributes(key serial primary key,status text ,values text,reference int[], type_key int);
CREATE INDEX object_attributes_reference on object_attributes USING gin(value_reference gin__int_ops)
Web 應用程式將首先檢索某些物件,然后檢索其各自的物件屬性值。一個物件在object_attributes表中可能有很多屬性值。
表中配置的用戶權限設定rls_permission,如果列is_all值為 true 則用戶可以看到所有行/物件,否則作為列中提到的參考reference。(參考rls_permission由其他介面填充的值,該介面具有完全訪問權限并從中獲取值object_attributes)
我在objects表上創建了低于行級別的策略。
CREATE POLICY no_rls_objects ON objects AS PERMISSIVE FOR ALL TO PUBLIC USING (TRUE);
CREATE POLICY rls_on_objects ON objects AS RESTRICTIVE TO web_app_user
USING(
(SELECT per.is_all FROM rls_permission per
WHERE (lower(per.upn) = lower(current_setting('db.rls_user'::text)))
)
OR (EXISTS ( SELECT 1 FROM object_attributes att
JOIN rls_permission per ON ((per.reference && att.reference)))
WHERE ((lower(per.upn) = lower(current_setting('db.rls_user'::text)))
AND (att.objects_key = objects.key)
)
)
)
rls_on_objects RESTRICTIVE 策略有兩個由 OR 分隔的 SELECT 查詢。
我無法創建兩個 RESTRICTIVE 策略,每個策略中有一個查詢,因為將使用 AND 組合兩個 RESTRICTIVE 策略。但我需要使用 OR 組合兩個查詢。
有沒有辦法重寫查詢并進行單一查詢?
因為兩個查詢都有(lower(per.upn) = lower(current_setting('db.rls_user'::text))),它在兩個查詢中都有計算,當 is_all 為 false 或 null 時,它檢查/執行第二個查詢。進行單個查詢將提高 RLS 性能,因為它不需要計算兩次。
謝謝
uj5u.com熱心網友回復:
嘗試這樣的事情:
SELECT per.is_all
OR EXISTS ( SELECT 1
FROM object_attributes att
WHERE att.reference && per.reference
AND att.objects_key = objects.key
)
FROM rls_permission per
WHERE lower(per.upn) = lower(current_setting('db.rls_user'::text))
或者這可能會更快:
SELECT per.is_all
OR bool_or(att.reference IS NOT NULL)
FROM rls_permission per
LEFT JOIN object_attributes att
ON att.reference && per.reference
WHERE lower(per.upn) = lower(current_setting('db.rls_user'::text))
AND att.objects_key = objects.key
GROUP BY per.is_all
uj5u.com熱心網友回復:
我認為您關注的是錯誤的問題。
重復WHERE子句不會成為主要的性能問題。在OR與該子查詢加入,將不得不為每個表行執行將是一個更大的問題。除了使用更簡單的權限系統之外,我并不知道如何改進它。
寬松的政策似乎很多余,你應該擺脫它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/366107.html
標籤:sql PostgreSQL的 查询优化 行级安全
上一篇:在PostgreSQLv14.x中使用json_build_object和SELECT陳述句的結果
下一篇:SQL:選擇“喜歡”2個元素
