PostgreSQL行级安全不使用表索引。

huangapple go评论44阅读模式
英文:

PostgreSQL Row-Level Security is NOT Using Table Indexes

问题

I have the following table with a million rows of data.

SELECT COUNT(*) FROM people; -- 1,000,000 rows

I have created the following 2 indexes:

Without the RLS enabled, I checked the explain plan of the following query and you can see that it is using the index that I have created for the ct_data JSONB column.

I enabled Row Level Security by issuing the following commands. The table policy is just a simple condition to have select access on the table.

With the RLS enabled, I rechecked the explain plan of the same query but this time, it did not use the index and it is doing a parallel sequential scan instead on the "people" table.

Why is RLS not using the indexes? Appreciate if you could provide some guidance to still implement RLS but not sacrifice performance.

At the moment, if I try to do an update on the ct_data column of the "people" table, it is taking so much time to complete the update especially after I add another simple table policy for the UPDATE DML operation like:

英文:

I have the following table with a million rows of data.

PostgreSQL行级安全不使用表索引。

SELECT COUNT(*) FROM people; -- 1,000,000 rows

I have created the following 2 indexes:

PostgreSQL行级安全不使用表索引。

Without the RLS enabled, I checked the explain plan of the following query and you can see that it is using the index that I have created for the ct_data JSONB column.

PostgreSQL行级安全不使用表索引。

I enabled Row Level Security by issuing the following commands. The table policy is just a simple condition to have select access on the table.

PostgreSQL行级安全不使用表索引。

With the RLS enabled, I rechecked the explain plan of the same query but this time, it did not use the index and it is doing a parallel sequential scan instead on the "people" table.

PostgreSQL行级安全不使用表索引。

Why is RLS not using the indexes? Appreciate if you could provide some guidance to still implement RLS but not sacrifice performance.

At the moment, if I try to do an update on the ct_data column of the "people" table, it is taking so much time to complete the update especially after I add another simple table policy for the UPDATE DML operation like:

PostgreSQL行级安全不使用表索引。

答案1

得分: 3

操作符->不是防泄漏的:

SELECT oprcode
FROM pg_operator
WHERE oprname = '->'
  AND oprleft = 'jsonb'::regtype
  AND oprright = 'text'::regtype;

      oprcode       
════════════════════
 jsonb_object_field
(1 )

SELECT proleakproof
FROM pg_proc
WHERE proname = 'json_object_field';

 proleakproof 
══════════════
 f
(1 )

不是防泄漏的函数和操作符不会在 RLS 策略的条件之前进行优化,出于安全原因。

解决方案是将id列从jsonb中提取出来,并将其定义为常规数值列。数值数据类型的=操作符是防泄漏的。

英文:

The problem is that the operator -> is not leakproof:

SELECT oprcode
FROM pg_operator
WHERE oprname = '->'
  AND oprleft = 'jsonb'::regtype
  AND oprright = 'text'::regtype;

      oprcode       
════════════════════
 jsonb_object_field
(1 row)

SELECT proleakproof
FROM pg_proc
WHERE proname = 'json_object_field';

 proleakproof 
══════════════
 f
(1 row)

Functions and operators that are not leakproof are not optimized to be applied before the condition from the RLS policy for security reasons.

The solution is to pull that id column out of the jsonb and define it a a regular numeric column. The = operators for numeric data types are leakproof.

huangapple
  • 本文由 发表于 2023年3月4日 04:58:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75631812.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定