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

Postgresql join_collapse_limit og tid til planlægning af forespørgsler

Den nye 9.4-version af PostgreSQL (endnu ikke udgivet på tidspunktet for skrivningen) vil tilføje planlægningstid til EXPLAIN og EXPLAIN ANALYZE , og så vil du være i stand til at bruge dem.

For ældre versioner er din antagelse rigtig, den bedre måde at bestemme planlægningstid på er ved at udføre en simpel EXPLAIN (ingen ANALYZE ) og kontrollere den tid, det tog, i psql du kan gøre det ved at aktivere \timing (Jeg gør det generelt på ~/.psqlrc ).

PostgreSQL hacker-teamet har allerede diskuteret om at hæve det til større værdier . Men det ser ud til, at de ikke kunne garantere, at det ville være godt for alle tilfælde.

Problemet er, at planlægningen af ​​at finde den bedste joinordre for N tabeller tager en O(N!) (faktoriel) tilgang. Og så tallene, forhøjelsen er meget høje, kan du nemt se det med følgende forespørgsel:

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

Som du kan se, laver vi som standard på 8 højst 40.000 sammenligninger, de 10 du foreslog får det til at gå til 3M, hvilket stadig ikke er særlig meget for moderne computere, men de næste værdier begynder at blive for store, de stiger bare for hurtigt, 20'eren er bare sindssyg (21! passer ikke engang til et 64 bit heltal).

Selvfølgelig kan du nogle gange indstille det til større værdier som 16, der (i teorien) kunne gøre op til omkring 20 billioner sammenligninger, og stadig have meget god planetid, det er fordi PostgreSQL skærer nogle stier under planlægningen og ikke behøver til altid kontrollere alle ordrer, men at antage, at det altid vil være tilfældet og gøre så høje værdier til standard, ser ikke ud som en god tilgang for mig. Der kan være nogle uventede forespørgsler i fremtiden, der gør det går til at kontrollere alle ordrer, og så har du kun én forespørgsel, der sætter din server ned.

Efter min erfaring antager jeg 10 som standardværdi på enhver installation i gode servere, nogle af dem bruger jeg endda 12. Jeg anbefaler dig at sætte den til 10, hvis du vil, og på nogle tidspunkter prøve at sætte den højere ( Jeg ville ikke gå længere end 12) og blive ved med at overvåge (tæt) for at se, hvordan den opfører sig.




  1. Bedre hukommelsesstyring (heap) på Solaris 10

  2. fjern alle numeriske tegn fra kolonnen mysql

  3. Oracle sql tutorial:Begrænsning af datasættet

  4. vigtigheden af ​​link-id i mysql_real_escape_string()