web-dev-qa-db-fra.com

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

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 j'ai exécuté EXPLAIN ANALYZE f1(), je n'ai 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.

20
skumar

Tout d'abord, la syntaxe correcte pour l'appel EXPLAIN a besoin d'un 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 un par un comme des 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 corps de fonction

Comme @Daniel l'a déjà commenté, vous pouvez utiliser le module supplémentaire auto_explain pour obtenir plus de détails ( lots 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

Des 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.

17
Erwin Brandstetter