Maison > base de données > tutoriel mysql > Comment empêcher plusieurs appels de fonction lors de l'utilisation de `(func()).*` dans les requêtes SQL ?

Comment empêcher plusieurs appels de fonction lors de l'utilisation de `(func()).*` dans les requêtes SQL ?

Linda Hamilton
Libérer: 2025-01-10 11:51:42
original
535 Les gens l'ont consulté

How to Prevent Multiple Function Calls When Using `(func()).*` in SQL Queries?

Éviter les appels de fonction répétés à l'aide de (func()).* dans les requêtes SQL

Lors de l'utilisation de fonctions renvoyant des tables ou des types composites, la syntaxe (func(arg)).* peut conduire à des appels de fonction redondants pour chaque colonne de sortie. Ce problème survient lors de l'appel de fonctions dans des tables ou des sous-requêtes, où (func()).* est souvent la seule approche pratique.

Le problème

De façon inattendue, (func()).* déclenche plusieurs exécutions de fonctions : un nombre égal au nombre de colonnes de sortie. Par exemple, une fonction renvoyant quatre colonnes peut être appelée huit fois au lieu des deux attendues.

Solutions

Pour remédier à cela, encapsulez l'appel de fonction dans une sous-requête :

<code class="language-sql">SELECT (mf).* FROM (
    SELECT my_func(x) AS mf FROM some_table
) sub;</code>
Copier après la connexion

Cela évite généralement les appels de fonctions supplémentaires et n'introduit pas d'analyses d'exécution supplémentaires. Pour une certitude absolue, envisagez l'OFFSET 0 astuce ou exploitez les limites de PostgreSQL dans l'optimisation CTE :

<code class="language-sql">SELECT (mf).* FROM (
    SELECT my_func(x) AS mf FROM some_table OFFSET 0
) sub;

WITH tmp(mf) AS (
    SELECT my_func(x) FROM some_table
)
SELECT (mf).* FROM tmp;</code>
Copier après la connexion

PostgreSQL 9.3 et versions ultérieures offrent une solution plus élégante utilisant LATERAL :

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

Cause fondamentale

L'expansion de (func()).* par l'analyseur dans une liste de colonnes est la cause sous-jacente. L'arbre analysé révèle que (func(x)).* se transforme en :

<code>(my_func(x)).i, (my_func(x)).j, (my_func(x)).k, (my_func(x)).l</code>
Copier après la connexion

Ce clonage de nœud inefficace, plutôt qu'une réplication de nœud d'appel de fonction unique, entraîne des appels répétés.

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal