行级安全性(RLS)性能在postgres中明显较慢。
描述: 以下是性能问题的示例演示。行级安全性(RLS)性能在postgres中明显较慢。
我们首先创建了两个表,启用了行级安全性并创建了策略。
表定义:
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;
创建角色:
CREATE ROLE tenant_grp_role_p_id;
创建策略:我希望有一个策略来选择数据,其中tenant_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')));
创建示例数据:
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');
问题:下面的查询不使用primary_key索引。
SELECT * FROM sample_schema.sample_table1 ST1, sample_schema.sample_table2 T2 WHERE ST1.id = ST2.table1_id AND ST1.id = 1;
问题:如果启用RLS,当我禁用RLS然后主键索引使用。为什么是不使用主键索引扫描?
注意:
答:如果我禁用行级安全性并运行上述查询,它使用索引。
B.below是解释计划当低级安全被禁用时的输出。
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);
C.if我启用低级别安全性并运行查询它不使用索引。
及以下是解释计划启用低级别安全性时的输出。
Nested Loop (cost=1.03..946.65 rows=79 width=1129) -> Seq Scan on sample_table2 st2 (cost=0.00..10.88 rows=1 width=1092) Filter: (table1_id = '1'::numeric) -> Subquery Scan on st1 (cost=1.03..934.98 rows=79 width=37)
Filter: (st1.id = '1'::numeric) -> Hash Join (cost=1.03..738.11 rows=15750 width=37) Hash Cond: ((st1_1.tenant_id)::name = pg_authid.rolname) -> Seq Scan on sample_table1 st1_1 (cost=0.00..578.00 rows=31500 width=37) -> Hash (cost=1.01..1.01 rows=1 width=68) -> Seq Scan on pg_authid (cost=0.00..1.01 rows=1 width=68) Filter: pg_has_role("current_user"(), oid, 'member'::text);
请帮我解决这个问题..
见this message thread详细信息的pgsql-general邮件列表上。
我最近应用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没有试图结合(和优化)安全条件和用户指定的条件:可以使用自定义函数来泄漏否则将被用户隐藏的值。
要创建这样一个观点,只是添加with (security_barrier)
的定义:
rhaas=# create or replace view unclassified_emp with (security_barrier) as
select * from emp where organization <> 'CIA';
CREATE VIEW
有在this detailed blog post的更多信息了。
请保留执行计划的格式和缩进。你将它们添加到你的问题的方式使它们无用。 –
这与这个问题是一样的:http://stackoverflow.com/questions/41169479/postgresql-multi-tenant-mode-not-using-index#comment69569639_41169479 –