Ho un problema con la pianificazione delle query PostgreSQL 9.6. La mia query è simile alla seguente:
SET role plain_user;
SELECT properties.*
FROM properties
JOIN entries_properties
ON properties.id = entries_properties.property_id
JOIN structures
ON structures.id = entries_properties.entry_id
WHERE structures."STRUKTURBERICHT" != ''
AND properties."COMPOSITION" LIKE 'Mo%'
AND (
properties."NAME" LIKE '%VASP-ase-preopt%'
OR properties."CALCULATOR_ID" IN (7,22,25)
)
AND properties."TYPE_ID" IN (6)
Ho abilitato la sicurezza a livello di riga per le tabelle utilizzate in precedenza.
con
set enable_nestloop = True
, il pianificatore di query esegue Nested Loop unendosi con un tempo di esecuzione totale di circa 37 secondi: https://explain.depesz.com/s/59BRcon
set enable_nestloop = False
, viene utilizzato il metodo Hash Join e il tempo di query è di circa 0,3 secondi: https://explain.depesz.com/s/PG8E
L'ho fatto VACUUM ANALYZE
prima di eseguire le query, ma non ha aiutato.
So che non è una buona pratica set enable_nestloop = False
e altre opzioni simili per il planner. Ma come potrei "convincere" il pianificatore a utilizzare i hash join senza disabilitare i loop nidificati?
Riscrivere la query è un'opzione.
Se eseguo la stessa query con un ruolo che ignora RLS, viene eseguita molto velocemente. La politica di sicurezza a livello di riga è simile alla seguente:
CREATE POLICY properties_select
ON properties
FOR SELECT
USING (
(
properties.ouid = get_current_user_id()
AND properties.ur
)
OR (
properties.ogid in (select get_current_groups_id())
AND properties.gr
)
OR properties.ar
);
Qualsiasi idea o suggerimento sarebbe molto apprezzato.
AND properties."TYPE_ID" IN (6);
e no= 6;
?