描述: 以下是性能问题的示例演示。
我们首先创建了两个表,启用了行级安全性并创建了策略。
表格定义:
filename = input('give me a filename: ', 's');
索引创建:
create table sample_schema.sample_table1(ID numeric(38) PRIMARY KEY NOT NULL,
tenant_id VARCHAR(255) NOT NULL,
Description VARCHAR(255)
);
create table sample_schema.sample_table2(ID2 numeric(38) PRIMARY KEY NOT NULL,
tenant_id VARCHAR(255) NOT NULL,
table1_id numeric (38),
Description2 VARCHAR(255)
);
启用行级安全性:
CREATE UNIQUE INDEX sample_table1_idx1 ON sample_schema.sample_table1(tenant_id,id);
创建角色:
ALTER TABLE sample_schema.sample_table1 ENABLE ROW LEVEL SECURITY;
创建策略:我希望策略选择其中tenant_id列值的角色与已登录用户相同的数据。
CREATE ROLE tenant_grp_role_p_id;
创建样本数据:
CREATE POLICY Tenant_Roles ON sample_schema.sample_table1 TO tenant_grp_role_p_id USING ((tenant_id) IN ( SELECT rolname FROM pg_roles WHERE pg_has_role( current_user, oid, 'member')));
问题:以下查询未使用primary_key索引。
insert into sample_schema.sample_table1 values (1,'user1_tenant1',1,'Table1 Data');
insert into sample_schema.sample_table2 values (2,'user1_tenant1',1,'Table2 Data');
问题:如果我禁用RLS,则使用主键索引。为什么在启用RLS时不使用主键索引扫描?
注意:
答:如果我禁用行级安全性并运行上述查询,它将使用索引
B.禁止低级安全性时的解释计划输出。
SELECT * FROM sample_schema.sample_table1 ST1, sample_schema.sample_table2 T2 WHERE ST1.id = ST2.table1_id AND ST1.id = 1;
C.如果我启用低级别安全性并运行查询,则不使用索引 以下是解释计划启用低级别安全性时的输出。
Nested Loop (cost=0.29..19.19 rows=1 width=1129) -> Index Scan using sample_table1_pkey on sample_table1 st1 (cost=0.29..8.30 rows=1 width=37)
Index Cond: (id = '1'::numeric) -> Seq Scan on sample_table2 st2 (cost=0.00..10.88 rows=1 width=1092) Filter: (table1_id = '1'::numeric);
请帮我解决这个问题..
答案 0 :(得分:5)
有关详细信息,请参阅pgsql-general邮件列表中的this message thread。
我最近将RLS应用于几个大型(几百万行)表 在我的9.5数据库中,注意到针对单个大型RLS的查询 受保护的表执行良好,但加入几个大的查询 受RLS保护的表执行得非常糟糕。解释计划显示了 优化器正在扫描整个表以强制执行RLS策略 在执行将减少查询的主键连接之前 从每个表中得到一行。显然会有表现 如果在策略检查之前执行了联接,那就更好了。
根据我的理解,RLS实现力求执行 在用户提供谓词检查之前进行策略检查以避免 泄露受保护的数据。
回复:
目前,RLS的加入案例并未得到很好的优化。有 正在努力改善这一点 - 见 https://www.postgresql.org/message-id/flat/8185.1477432701%40sss.pgh.pa.us - 但它不会在v10之前投入生产。
和
您可以使用同一用户拥有的安全屏障视图 下面的表是由,它将绕过RLS 表本身,因此你需要实现 安全障碍视图中适当的评估。
所以你可以等待PG10,或尝试使用security barrier view代替。该博客文章还解释了为什么Postgres不会尝试组合(和优化)安全条件和用户指定的条件:自定义函数可用于泄漏否则将被用户隐藏的值。
要创建此类视图,只需将 lat += 0.5 * pi;
=> 0x0000000000f34ca3 <+327>: mov -0x20(%rbp),%rax
0x0000000000f34ca7 <+331>: movsd (%rax),%xmm1
0x0000000000f34cab <+335>: movsd 0xcfee57d(%rip),%xmm2 # 0xdf23230 <_ZN3abc2piE>
0x0000000000f34cb3 <+343>: movsd 0x127735(%rip),%xmm0 # 0x105c3f0
0x0000000000f34cbb <+351>: mulsd %xmm2,%xmm0
0x0000000000f34cbf <+355>: addsd %xmm1,%xmm0
0x0000000000f34cc3 <+359>: mov -0x20(%rbp),%rax
0x0000000000f34cc7 <+363>: movsd %xmm0,(%rax)
添加到定义:
with (security_barrier)
this detailed blog post中还有更多信息。