Quelle est la différence entre le LATÉRAL et une sous-requête dans PostgreSQL?
Depuis Postgres est sorti avec la capacité de faire LATERAL
jointures, j'ai lu sur elle, depuis que je fais de données complexes dumps pour mon équipe avec beaucoup de l'inefficacité des sous-requêtes qui font de la requête globale de prendre quatre minutes ou plus.
Je comprends que LATERAL
rejoint peut-être pouvoir m'aider, mais même après avoir lu des articles comme cette une de Tas Analytics, je n'ai toujours pas tout suivre.
Ce qui est le cas d'utilisation pour un LATERAL
rejoindre? Quelle est la différence entre un LATERAL
rejoindre et d'une sous-requête?
- blog.heapanalytics.com/... et explainextended.com/2009/07/16/inner-join-vs-cross-apply (SQL Server
apply
est le même que lelateral
de la norme SQL)
Vous devez vous connecter pour publier un commentaire.
Plus comme un corrélation sous-requête
Un
LATERAL
rejoindre (Postgresql 9.3 ou une version ultérieure) est plus comme un sous-requête en corrélation, pas un simple sous-requête. Comme Andomar souligné, une fonction ou une sous-requête pour le droit d'unLATERAL
de jointure doit être évaluée une fois pour chaque ligne de gauche de celui - ci- tout comme un corrélation sous-requête - tout en un simple sous-requête (expression de table) est évalué une fois seulement. (Le planificateur de requête a des moyens pour optimiser les performances, soit, si.)Cette réponse a des exemples de code pour les deux côte à côte, résoudre le même problème:
Pour le retour plus d'une colonne, un
LATERAL
jointure est généralement plus simple, plus propre et plus rapide.Aussi, n'oubliez pas que l'équivalent d'une sous-requête corrélée est
LEFT JOIN LATERAL ... ON true
:Lire le manuel sur
LATERAL
Il est plus autoritaire que tout ce que nous allons mettre dans les réponses ici:
Les choses d'une sous-requête ne peut pas faire
Il sont choses qu'un
LATERAL
rejoindre ne peut, mais un (corrélation) sous-requête ne peut pas (facilement). Une sous-requête en corrélation ne peut retourner qu'une seule valeur, et non pas de plusieurs colonnes et plusieurs lignes à l'exception de nu appels de fonction (qui multiplient les lignes de résultats si ils retourner plusieurs lignes). Mais même certains set‑retour fonctions ne sont autorisés que dans laFROM
clause. Commeunnest()
avec plusieurs paramètres dans Postgresql 9.4 ou plus tard. Le manuel de:Si cela fonctionne, mais ne peut pas facilement être remplacé par une sous-requête:
La virgule (
,
) dans leFROM
clause est à court de notation pour lesCROSS JOIN
.LATERAL
est supposé automatiquement pour les fonctions de table.Plus sur le cas particulier de
UNNEST( array_expression [, ... ] )
:Jeu-de retour des fonctions dans le
SELECT
listeVous pouvez également utiliser le set-de retour des fonctions comme
unnest()
dans leSELECT
liste directement. Cette figure comportement surprenant à plus d'une fonction dans le mêmeSELECT
liste jusqu'à Postgres 9.6. Mais il a finalement été désinfectés avec Postgres 10 et est une alternative valable maintenant (même si c'est pas le standard SQL). Voir:Appuyant sur l'exemple ci-dessus:
Comparaison:
dbfiddle pour pg 9.6 ici
dbfiddle pour pg 10 ici
Clarifier la désinformation
Le manuel de:
De sorte que ces deux requêtes sont valables (même si pas particulièrement utile):
Tandis que celui-ci n'est pas:
C'est pourquoi @Andomar de l' exemple de code est correct (le
CROSS JOIN
ne nécessite pas de condition de jointure) et @Attila duestn'est pas valide.LATERAL
sous-requête: gis.stackexchange.com/a/230070/7244La différence entre un non-
lateral
et unlateral
joindre se trouve dans le fait que vous pouvez regarder pour la main gauche de la table en ligne. Par exemple:Cet "extérieur" signifie que la sous-requête doit être évalué plus d'une fois. Après tout,
t1.col1
peut prendre beaucoup de valeurs.En revanche, la sous-requête après un non-
lateral
jointure peut être évaluée une fois:Que nécessaire sans
lateral
, la requête interne ne dépendent en aucune manière de la requête externe. Unlateral
requête est un exemple decorrelated
requête, en raison de sa relation avec les lignes à l'extérieur de la requête elle-même.D'abord, Et transversales Appliquer est la même chose. Par conséquent vous pouvez également lire sur la Croix s'Appliquent. Depuis qu'il a été mis en œuvre dans SQL Server pour les âges, vous trouverez plus d'informations à ce sujet alors Latérale.
Deuxième, selon ma compréhension, il n'y a rien que vous pouvez faire à l'aide de sous-requête au lieu d'utiliser latérale. Mais:
Envisager la suite de la requête.
Vous pouvez utiliser latérale dans cette condition.
Dans cette requête, vous ne pouvez pas utiliser des rejoindre, en raison de la limite de la clause.
Latérale ou de la Croix-Appliquer peut être utilisé quand il n'est pas simple condition de jointure.
Il y a plus d'utilisations pour les latérales ou de la croix appliquer, mais c'est plus commun que j'ai trouvé.
lateral
au lieu deapply
. Peut-être que Microsoft a breveté la syntaxe?lateral
est dans le standard SQL maisapply
ne l'est pas.LEFT JOIN
exige une condition de jointure. FaireON TRUE
sauf si vous souhaitez restreindre quelque sorte.cross join
ou unon
conditionX.Fk1
car il n'est pas dans le résultat de la sous-requête. Si vous incluezFk1
dans la sous-requête, il sera formellement correct, mais présentent toujours exotiques comportement. Il sélectionne un arbitraire ligne deB
et ne rejoint-il àA
siFk1
correspond àA.PK
.and Limit 1
? C'est qu'une faute de frappe ou un valide construire avec lequel je ne suis pas familier?Une chose que personne n'a souligné, c'est que vous pouvez utiliser
LATERAL
requêtes pour appliquer une fonction définie par l'utilisateur sur chaque ligne sélectionnée.Par exemple:
C'est la seule façon que je sais comment faire ce genre de chose dans PostgreSQL.