sql >> Database >  >> RDS >> PostgreSQL

Postgresql join_collapse_limit en tijd voor queryplanning

De nieuwe 9.4-versie van PostgreSQL (nog niet vrijgegeven op het moment van schrijven) gaat planningstijd toevoegen aan EXPLAIN en EXPLAIN ANALYZE , en dus kun je die gebruiken.

Voor oudere versies is uw veronderstelling juist, de betere manier om de planningstijd te bepalen is door een eenvoudige EXPLAIN uit te voeren. (geen ANALYZE ) en controleer de tijd die het kostte, in psql u kunt dit doen door de \timing (Ik doe dat meestal op ~/.psqlrc ).

Het PostgreSQL-hackersteam heeft al gesproken over het verhogen van het naar grotere waarden . Maar het lijkt erop dat ze niet konden garanderen dat het in alle gevallen goed zou zijn.

Het probleem is dat de planning om de beste join-volgorde te vinden voor N tabellen neemt een O(N!) (faculteits)benadering. En dus, het aantal verhogingen is erg hoog, dat kun je eenvoudig zien met de volgende vraag:

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

Zoals je kunt zien, doen we bij de standaardwaarde van 8 maximaal ongeveer 40K-vergelijkingen, de 10 die je hebt voorgesteld, zorgt ervoor dat het naar 3M gaat, wat nog steeds niet veel is voor moderne computers, maar de volgende waarden beginnen te groot te worden, het neemt alleen maar toe te snel, de 20 is gewoon krankzinnig (21! past niet eens op een 64-bits geheel getal).

Natuurlijk kun je het soms instellen op grotere waarden zoals 16, die (in theorie) tot ongeveer 20 biljoen vergelijkingen kunnen maken, en nog steeds een zeer goede plantijd hebben, dat komt omdat PostgreSQL tijdens het plannen een aantal paden snijdt en niet nodig is naar altijd controleer alle bestellingen, maar ervan uitgaande dat dit altijd het geval zal zijn en zulke hoge waarden de standaard maakt, lijkt me geen goede benadering. Er kan in de toekomst een onverwachte vraag zijn die ervoor zorgt dat alle bestellingen worden gecontroleerd en dan heb je maar één vraag die je server uitschakelt.

In mijn ervaring neem ik de 10 aan als standaardwaarde voor elke installatie op goede servers, sommige gebruik ik zelfs 12. Ik raad je aan om het in te stellen op 10, als je wilt, en probeer het soms hoger in te stellen ( Ik zou niet verder gaan dan 12) en (nauwlettend) blijven volgen om te zien hoe het zich gedraagt.




  1. Wijs dezelfde id toe aan rijen met dezelfde combinatie van gegevens

  2. JDBC-verbindingen in pool sluiten

  3. Privé berichtensysteem. Het laatste bericht van elk gesprek weergeven

  4. Snelle tips over relationeel database-ontwerp voor MySQL