PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Postgresql join_collapse_limit et temps de planification des requêtes

La nouvelle version 9.4 de PostgreSQL (pas encore publiée au moment de la rédaction de cet article) va ajouter du temps de planification dans EXPLAIN et EXPLAIN ANALYZE , et vous pourrez donc les utiliser.

Pour les anciennes versions, votre hypothèse est juste, la meilleure façon de déterminer le temps de planification est d'exécuter un simple EXPLAIN (pas d'ANALYZE ) et en vérifiant le temps qu'il a fallu, en psql vous pouvez le faire en activant le \timing (Je le fais généralement à ~/.psqlrc ).

L'équipe de hackers de PostgreSQL a déjà discuté de l'augmenter à des valeurs plus élevées . Mais il semble qu'ils ne pouvaient pas garantir que ce serait bon pour tous les cas.

Le problème est que la planification pour trouver le meilleur ordre de jointure pour N tables prend un O(N!) approche (factorielle). Et donc, les chiffres de l'augmentation sont très élevés, vous pouvez simplement le voir avec la requête suivante :

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

Comme vous pouvez le voir, à la valeur par défaut de 8, nous faisons au maximum environ 40 000 comparaisons, le 10 que vous avez proposé le fait passer à 3 M, ce qui n'est pas encore très important pour les ordinateurs modernes, mais les valeurs suivantes commencent à devenir trop grandes, elles augmentent juste trop rapide, le 20 est tout simplement fou (21 ! ne correspond même pas à un entier de 64 bits).

Bien sûr, vous pouvez parfois le définir sur des valeurs plus grandes comme 16, qui pourraient (en théorie) faire jusqu'à environ 20 billions de comparaisons, et avoir toujours un très bon temps de planification, c'est parce que PostgreSQL coupe certains chemins lors de la planification et n'a pas besoin pour toujours vérifier toutes les commandes, mais en supposant que ce sera toujours le cas et que des valeurs aussi élevées soient la valeur par défaut, cela ne me semble pas être une bonne approche. Il peut y avoir une requête inattendue à l'avenir qui oblige à vérifier toutes les commandes, puis vous n'avez qu'une seule requête qui arrête votre serveur.

D'après mon expérience, je suppose le 10 comme valeur par défaut sur toute installation sur de bons serveurs, certains d'entre eux j'utilise même 12. Je vous recommande de le régler sur 10, si vous le souhaitez, et parfois, essayez de le régler plus haut ( Je n'irais pas au-delà de 12) et continuerais à surveiller (de près) pour voir comment il se comporte.