Domanda

Ho una situazione molto simile a quella descritto qui:

Ho una situazione SaaS in cui sto usando 1000+ schemi in un singolo database (ogni schema contiene le stesse tabelle, solo dati diversi per inquilino). Ho usato gli schemi in modo che i server di app condivisi potessero condividere una connessione al singolo database per tutti gli schemi. Le cose funzionano bene.

E, mentre l'applicazione stessa sembra funzionare bene, alcune domande che coinvolgono cataloghi di sistema sono molto lente. Anche, psqlLa completamento automatico è totalmente inutile e \dt è molto lento.

In particolare, devo calcolare la dimensione del disco di ogni schema usando qualcosa del genere:

SELECT sum(pg_total_relation_size(c.oid)) AS size
FROM   pg_namespace n
JOIN   pg_class     c ON c.relnamespace = n.oid
WHERE  n.nspname = 'abbiecarmer'
AND    c.relkind = 'r';

che è abbastanza lento. Guardando il piano di query, vedo

Aggregate  (cost=136903.16..136903.17 rows=1 width=4) (actual time=1024.420..1024.420 rows=1 loops=1)             
  ->  Hash Join  (cost=8.28..136902.86 rows=59 width=4) (actual time=143.247..1016.749 rows=60 loops=1)           
        Hash Cond: (c.relnamespace = n.oid)                                                                       
        ->  Seq Scan on pg_class c  (cost=0.00..133645.24 rows=866333 width=8) (actual time=0.045..943.029 rows=879788 loops=1)                                                                                                    │
              Filter: (relkind = 'r'::"char")                                                                     
              Rows Removed by Filter: 2610112                                                                     
        ->  Hash  (cost=8.27..8.27 rows=1 width=4) (actual time=0.032..0.032 rows=1 loops=1)                      
              Buckets: 1024  Batches: 1  Memory Usage: 1kB                                                        
              ->  Index Scan using pg_namespace_nspname_index on pg_namespace n  (cost=0.00..8.27 rows=1 width=4)(actual time=0.029..0.030 rows=1 loops=1)                                                                        │
                    Index Cond: (nspname = 'abbiecarmer'::name)                                                   
Total runtime: 1024.476 ms                                                                                        

Il che, se lo capisco bene, dice che il 90% del tempo di query viene speso in sequenza pg_class relazione.

Ho interrotto il postmaster, eseguito il backend in modalità utente singolo e ho aggiunto i seguenti indici:

create index pg_class_relnamespace_index on pg_class(relnamespace);
REINDEX INDEX pg_class_relnamespace_index;

create index pg_class_reltablespace_index on pg_class(reltablespace);
REINDEX INDEX pg_class_reltablespace_index;

(Ho anche migliaia di tablespace). Ora la query è ~ 100 volte più veloce e il piano sembra molto più bello:

Aggregate  (cost=846.91..846.92 rows=1 width=4) (actual time=10.609..10.610 rows=1 loops=1)                       
  ->  Nested Loop  (cost=0.00..846.61 rows=60 width=4) (actual time=0.069..0.320 rows=60 loops=1)                 
        ->  Index Scan using pg_namespace_nspname_index on pg_namespace n  (cost=0.00..8.27 rows=1 width=4) (actual time=0.023..0.024 rows=1 loops=1)                                                                              │
              Index Cond: (nspname = 'abbiecarmer'::name)                                                        
        ->  Index Scan using pg_class_relnamespace_index on pg_class c  (cost=0.00..837.59 rows=75 width=8) (actual time=0.043..0.271 rows=60 loops=1)                                                                             │
              Index Cond: (relnamespace = n.oid)                                                                 
              Filter: (relkind = 'r'::"char")                                                                    
              Rows Removed by Filter: 102                                                                        
Total runtime: 10.696 ms                                                                                         

Tuttavia, nel thread sopra, Tom Lane, che è uno dei collaboratori di Postgres Core, dice:

Ci sono molti gotchas qui, in particolare che la sessione in cui si crea l'indice non saprà che è lì (quindi in questo caso, un reindEx su PG_Class sarebbe probabilmente consigliabile in seguito). Penso ancora che saresti pazzo per provarlo su un database di produzione, ma ...

Sono anche preoccupato per il fatto che la modifica dei cataloghi di sistema sembra essere completamente disabilitato in Postgres 9.0 e 9.1 (sto usando 9.2) - Suppongo che sia stato fatto per un motivo?

Quindi, la domanda è: Quali sono i Gotchas nell'aggiungere un indice a un catalogo di sistema in Postgres e sarò pazzo se lo (alla fine) lo faccio su un sistema di produzione?

Nessuna soluzione corretta

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top