EXPLAIN ANALYZE ne montre aucun détail pour les requêtes à l'intérieur d'une fonction plpgsql

18

J'utilise une fonction PL / pgSQL dans PostgreSQL 9.3 avec plusieurs requêtes complexes à l'intérieur:

create function f1()
  returns integer as
$$
declare

event tablename%ROWTYPE;
....
....

begin

FOR event IN
   SELECT * FROM tablename WHERE condition
LOOP
   EXECUTE 'SELECT f2(event.columnname)' INTO dummy_return;
END LOOP;

...

INSERT INTO ... FROM a LEFT JOIN b ... LEFT JOIN c WHERE ...

UPDATE T SET cl1 = M.cl1 FROM M WHERE M.pkcols = T.pkcols;

...

end
$$ language plpgsql;

Si je courais EXPLAIN ANALYZE f1(), je n'obtiens que le temps total, mais pas de détails. Existe-t-il un moyen d'obtenir des résultats détaillés pour toutes les requêtes de la fonction?

Si les requêtes dans la fonction ne devaient pas être optimisées par Postgres, je demanderais également une explication.

skumar
la source
2
auto_explain.log_nested_statementspourrait aider. Voir postgresql.org/docs/9.3/static/auto-explain.html
Daniel Vérité

Réponses:

15

Tout d'abord, la syntaxe correcte pour l' EXPLAINappel nécessite a SELECT. Vous ne pouvez pas simplement écrire le nom de la fonction nue en SQL:

EXPLAIN ANALYZE SELECT f1();

Optimisation

Les fonctions PL / pgSQL sont des cases noires pour le planificateur de requêtes. Les requêtes à l'intérieur sont optimisées comme les autres requêtes, mais séparément et une par une comme les instructions préparées, et le plan d'exécution peut être mis en cache pour la durée de la session. Détails:

EXPLAIN organes fonctionnels

Comme @Daniel l'a déjà commenté, vous pouvez utiliser le module supplémentaire auto_explain pour obtenir plus de détails ( beaucoup de détails). Les instructions à l'intérieur des fonctions plpgsql sont considérées comme des "instructions imbriquées". Assurez-vous de régler

SET auto_explain.log_nested_statements = ON

Instructions détaillées:

Par exception à la règle, les fonctions SQL très simples (pas plpgsql) peuvent être "intégrées", c'est-à-dire que le code de fonction est inséré dans la requête externe et tout est exécuté comme s'il n'y avait pas de fonction au départ. Le plan de requête comprend des informations détaillées dans de tels cas.

Erwin Brandstetter
la source
Après avoir activé 'auto_explain' comme ci-dessous, chargez 'auto_explain'; set auto_explain.log_min_duration = 0; set auto_explain.log_nested_statements = ON; SET auto_explain.log_analyze = true; Je reçois moins de msg dans le fichier journal, '2014-12-08 18:21:59 IST LOG: n'a pas pu recevoir de données du client: Aucune connexion n'a pu être établie car la machine cible l'a activement refusée' peut-on me guider le vrai problème ....
skumar
Remarque: Après avoir exécuté la fonction plpgsql, je dépasse le msg dans le fichier journal.
skumar