描述: 以下是性能問題的示例演示。行級安全性(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);
請幫我解決這個問題..
請保留執行計劃的格式和縮進。你將它們添加到你的問題的方式使它們無用。 –
這與這個問題是一樣的:http://stackoverflow.com/questions/41169479/postgresql-multi-tenant-mode-not-using-index#comment69569639_41169479 –