Maison >base de données >tutoriel mysql >Pourquoi `(func()).*` dans PostgreSQL provoque-t-il plusieurs évaluations de fonctions ?

Pourquoi `(func()).*` dans PostgreSQL provoque-t-il plusieurs évaluations de fonctions ?

Linda Hamilton
Linda Hamiltonoriginal
2025-01-10 11:37:42920parcourir

Why Does `(func()).*` in PostgreSQL Cause Multiple Function Evaluations?

*Problème de performances PostgreSQL : la syntaxe `(func()).` et les appels de fonctions redondants**

Cet article examine un problème de performances dans PostgreSQL lié à la syntaxe (func()).* lorsqu'elle est utilisée avec des fonctions renvoyant des types ou des ensembles composites. L'observation originale, présentée dans la requête ci-dessous, met en évidence le comportement inattendu :

<code class="language-sql">SELECT (func(3)).*; -- Leads to multiple function calls</code>

Le problème : les évaluations fonctionnelles excessives

Le problème principal est que (func()).* déclenche un appel de fonction distinct pour chaque colonne dans la sortie de la fonction. Une fonction renvoyant quatre colonnes, par exemple, peut entraîner huit appels de fonction au lieu des deux prévus. Cela contraste fortement avec la syntaxe alternative, telle que :

<code class="language-sql">SELECT N, func(N); -- More efficient approach</code>

Solution : Réécriture efficace des requêtes

Pour contourner les appels excessifs, une sous-requête fournit une solution de contournement. Bien que généralement efficace, cette solution n'est pas parfaite et peut introduire d'autres considérations en matière de performances.

Pour PostgreSQL 9.3 et versions ultérieures, le mot-clé LATERAL offre une solution supérieure :

<code class="language-sql">SELECT mf.*
FROM some_table
LEFT JOIN LATERAL my_func(some_table.x) AS mf ON true;</code>

Cause fondamentale : comportement de l'analyseur PostgreSQL

La cause première réside dans la façon dont l'analyseur PostgreSQL gère le caractère générique * dans la construction (func()).*. L'expansion des caractères génériques dans des colonnes individuelles lors de l'analyse est la source des appels de fonction redondants.

Benchmark des performances et démonstration

Un exemple de fonction personnalisée démontre l'écart de performances entre la syntaxe problématique et les solutions de contournement suggérées. Les tests montrent que l'approche sous-requête (ou CTE) offre des améliorations significatives des performances.

Conclusion : Optimisation des requêtes dans PostgreSQL

Bien que le problème d'appel de fonctions multiples avec (func()).* reste un comportement connu, les solutions de contournement, notamment en utilisant LATERAL (PostgreSQL 9.3), fournissent des stratégies efficaces aux développeurs pour optimiser les performances des requêtes et réduire les évaluations de fonctions inutiles.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn