Многопользовательский режим Postgresql без использования индекса

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);        

CREATE ROLE tenant_grp_role_p_id
         NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;

create user user1_tenant1;
GRANT tenant_grp_role_p_id to user1_tenant1;
GRANT all on schema sample_schema to tenant_grp_role_p_id;
GRANT select,update,insert,delete on sample_schema.sample_table1  
        TO tenant_grp_role_p_id;


ALTER TABLE sample_schema.sample_table1 ENABLE ROW LEVEL SECURITY;
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','My Data One');
  insert...
  insert...

  -- Inserted around 30000 Rows

  insert into sample_schema.sample_table2 values       
  (1,'user1_tenant1',1,'Table2 Data1');

  -- Inserted around 20 Rows

  select * from sample_schema.sample_table1 

  set role to user1_tenant1;

  SELECT * 
  FROM sample_schema.sample_table1 ST1, 
    sample_schema.sample_table2 ST2
  WHERE ST1.id = ST2.table1_id
    AND ST1.id = 1;

Объясните результат плана без политики

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)

С многопользовательской политикой

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)

Без включенной многопользовательской политики Postgresql использует индекс, тогда как после включения политики он не использует ни индекс, ни PKey, ни любой другой индекс, который я создал.

Какие настройки требуются в Postgresql для использования индексов, которые мы создали, когда включена безопасность на уровне строк.


person Aravinda Mundakana    schedule 15.12.2016    source источник
comment
Какие запросы? Пожалуйста, прочтите Как задать вопрос. А вот отличное место для СТАРТ чтобы узнать, как повысить качество вопросов и получить более качественные ответы.   -  person Juan Carlos Oropeza    schedule 15.12.2016
comment
Известное ограничение текущей реализации RLS заключается в том, что она создает неоптимальные планы. Вероятно, вы мало что можете сделать.   -  person a_horse_with_no_name    schedule 16.12.2016
comment
PG 10 теперь должен работать быстрее: github.com/postgres/postgres/commit/   -  person mkurz    schedule 16.04.2018