PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Postgresql join_collapse_limit e tempo per la pianificazione delle query

La nuova versione 9.4 di PostgreSQL (non ancora rilasciata al momento della stesura di questo articolo) aggiungerà tempo di pianificazione in EXPLAIN e EXPLAIN ANALYZE , e così potrai usarli.

Per le versioni precedenti, la tua ipotesi è giusta, il modo migliore per determinare il tempo di pianificazione è eseguire un semplice EXPLAIN (nessun ANALYZE ) e controllando il tempo impiegato, in psql puoi farlo abilitando il \timing (In genere lo faccio su ~/.psqlrc ).

Il team di hacker di PostgreSQL ha già discusso di portarlo a valori maggiori . Ma sembra che non potessero garantire che sarebbe stato utile per tutti i casi.

Il problema è che la pianificazione per trovare il miglior ordine di unione per N tabelle accetta un O(N!) approccio (fattoriale). E quindi, i numeri dell'aumento sono molto alti, puoi facilmente vederlo con la seguente query:

$ SELECT i, (i)! AS num_comparisons FROM generate_series(8, 20) i;
 i  |   num_comparisons   
----+---------------------
  8 |               40320
  9 |              362880
 10 |             3628800
 11 |            39916800
 12 |           479001600
 13 |          6227020800
 14 |         87178291200
 15 |       1307674368000
 16 |      20922789888000
 17 |     355687428096000
 18 |    6402373705728000
 19 |  121645100408832000
 20 | 2432902008176640000
(13 rows)

Come puoi vedere, al valore predefinito di 8 facciamo al massimo circa 40K confronti, il 10 che hai proposto lo fa passare a 3M, che non è ancora molto per i computer moderni, ma i valori successivi iniziano a diventare troppo grandi, semplicemente aumentano troppo veloce, il 20 è semplicemente folle (21! non si adatta nemmeno a un intero a 64 bit).

Ovviamente, a volte puoi impostarlo su valori più grandi come 16, che potrebbero (in teoria) fare fino a circa 20 trilioni di confronti e avere comunque un tempo di planata molto buono, questo perché PostgreSQL ha tagliato alcuni percorsi durante la pianificazione e non è necessario a sempre controlla tutti gli ordini, ma supponendo che sarà sempre così e imposta valori così alti come predefiniti, non mi sembra un buon approccio. Potrebbero esserci alcune query inaspettate in futuro che ti portano a controllare tutti gli ordini e quindi hai un'unica query che interrompe il tuo server.

Nella mia esperienza, presumo il 10 come valore predefinito su qualsiasi installazione in buoni server, alcuni di loro uso anche 12. Ti consiglio di impostarlo su 10, se lo desideri, e, a volte, prova a impostarlo più alto ( Non andrei oltre 12) e continuerei a monitorare (da vicino) per vedere come si comporta.