sql >> Databasteknik >  >> RDS >> PostgreSQL

Postgresql join_collapse_limit och tid för frågeplanering

Den nya 9.4-versionen av PostgreSQL (ännu inte släppt när detta skrivs) kommer att lägga till planeringstid i EXPLAIN och EXPLAIN ANALYZE , och så kommer du att kunna använda dem.

För äldre versioner är ditt antagande rätt, det bättre sättet att bestämma planeringstiden är genom att utföra en enkel EXPLAIN (ingen ANALYZE ) och kontrollera tiden det tog, i psql du kan göra det genom att aktivera \timing (Jag gör vanligtvis det på ~/.psqlrc ).

PostgreSQL-hackarteamet har redan diskuterat om att höja det till större värden . Men det verkar som om de inte kunde garantera att det skulle vara bra för alla fall.

Problemet är att man planerar att hitta den bästa joinordern för N tabeller tar en O(N!) (faktoriellt) tillvägagångssätt. Och så, siffrorna som höjningen är mycket höga, du kan enkelt se det med följande fråga:

$ 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, vid standardvärdet 8 gör vi som mest om 40K jämförelser, de 10 du föreslog gör att det går till 3M, vilket fortfarande inte är särskilt mycket för moderna datorer, men nästa värden börjar bli för stora, de bara ökar för snabbt, 20:an är bara galen (21! passar inte ens ett 64-bitars heltal).

Naturligtvis, ibland kan du ställa in den på större värden som 16, som (i teorin) kan göra upp till cirka 20 biljoner jämförelser, och fortfarande har mycket bra hyvlingstid, det beror på att PostgreSQL klipper några vägar medan du planerar och inte behöver till alltid kontrollera alla beställningar, men att anta att det alltid kommer att vara fallet och göra så höga värden till standard, ser inte ut som ett bra tillvägagångssätt för mig. Det kan komma en oväntad fråga i framtiden som gör att det går till att kontrollera alla beställningar och sedan har du bara en fråga som lägger ner din server.

Enligt min erfarenhet antar jag 10 som standardvärde på alla installationer i bra servrar, vissa av dem använder jag till och med 12. Jag rekommenderar dig att ställa in den till 10, om du vill, och vid vissa tillfällen, prova att ställa in den högre ( Jag skulle inte gå längre än 12) och fortsätta övervaka (nära) för att se hur det beter sig.




  1. Subquery returnerar mer än en radslösning för uppdateringsfråga med select-sats

  2. Kan jag använda Oracles analytiska funktion här?

  3. Behöver du hjälp med att skapa en fråga i SQL?

  4. gruppera efter prisklass