描述 :
这是性能问题的示例演示。

我们首先创建了两个表,启用了行级安全性,还创建了策略。

表定义:

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 index。
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.以下是说明计划禁用低级别安全性时的输出。
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.如果启用了低级安全性并运行查询,则它不使用索引。
下面是启用低级安全性时的说明计划输出。
 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);

请帮助我解决此问题..

最佳答案

有关详细信息,请参见pgsql常规邮件列表上的this message thread



以及回应:



和:



因此,您可以等待PG10,或者尝试使用security barrier view。那篇博客文章还解释了为什么Postgres不尝试结合(优化)安全性条件和用户指定的条件:自定义函数可用于泄漏本来对用户隐藏的值。

要创建这样的 View ,只需将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中也有更多信息。

关于sql - 在postgres中,行级安全性(RLS)性能显着降低。,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41186880/

10-15 18:15