Quel est l'objectif principal de CROSS APPLY ?
J'ai lu (vaguement, à travers des publications sur Internet) qui cross apply
peut être plus efficace lors de la sélection de plus grands ensembles de données si vous partitionnez. (La pagination vient à l'esprit)
Je sais également que CROSS APPLY
cela ne nécessite pas un UDF comme table de droite.
Dans la plupart des INNER JOIN
requêtes (relations un-à-plusieurs), je pouvais les réécrire pour les utiliser CROSS APPLY
, mais elles me donnent toujours des plans d'exécution équivalents.
Quelqu'un peut-il me donner un bon exemple du moment où cela CROSS APPLY
fait une différence dans les cas où INNER JOIN
cela fonctionnera également?
Éditer:
Voici un exemple trivial, où les plans d'exécution sont exactement les mêmes. (Montrez-moi celui où ils diffèrent et où cross apply
est plus rapide / plus efficace)
create table Company (
companyId int identity(1,1)
, companyName varchar(100)
, zipcode varchar(10)
, constraint PK_Company primary key (companyId)
)
GO
create table Person (
personId int identity(1,1)
, personName varchar(100)
, companyId int
, constraint FK_Person_CompanyId foreign key (companyId) references dbo.Company(companyId)
, constraint PK_Person primary key (personId)
)
GO
insert Company
select 'ABC Company', '19808' union
select 'XYZ Company', '08534' union
select '123 Company', '10016'
insert Person
select 'Alan', 1 union
select 'Bobby', 1 union
select 'Chris', 1 union
select 'Xavier', 2 union
select 'Yoshi', 2 union
select 'Zambrano', 2 union
select 'Player 1', 3 union
select 'Player 2', 3 union
select 'Player 3', 3
/* using CROSS APPLY */
select *
from Person p
cross apply (
select *
from Company c
where p.companyid = c.companyId
) Czip
/* the equivalent query using INNER JOIN */
select *
from Person p
inner join Company c on p.companyid = c.companyId
la source
CROSS APPLY
a son utilisation évidente en permettant à un ensemble de dépendre d'un autre (contrairement à l'JOIN
opérateur), mais cela ne vient pas sans coût: il se comporte comme une fonction qui opère sur chaque membre de l' ensemble gauche , donc, en termes SQL Server, il effectuez toujours unLoop Join
, ce qui n'est presque jamais le meilleur moyen de joindre des ensembles. Donc, utilisez-leAPPLY
quand vous en avez besoin, mais n'en abusez pasJOIN
.Réponses:
Voir l'article dans mon blog pour une comparaison détaillée des performances:
INNER JOIN
contre.CROSS APPLY
CROSS APPLY
fonctionne mieux sur des choses qui n'ont pas deJOIN
condition simple .Celui-ci sélectionne les
3
derniers enregistrements det2
pour chaque enregistrement parmit1
:Il ne peut pas être facilement formulé avec une
INNER JOIN
condition.Vous pourriez probablement faire quelque chose comme ça en utilisant
CTE
la fonction s et window:, mais c'est moins lisible et probablement moins efficace.
Mise à jour:
Je viens de vérifier.
master
est un tableau sur les20,000,000
enregistrements avec unPRIMARY KEY
onid
.Cette requête:
fonctionne pendant près de
30
secondes, tandis que celui-ci:est instantané.
la source
TVF
avecINNER JOIN
?CROSS APPLY
, il a demandé quand le choisirINNER JOIN
, quand cela fonctionnerait aussi.lateral join
SQL standard (ANSI)cross apply
vous permet parfois de faire des choses que vous ne pouvez pas faire avecinner join
.Exemple (une erreur de syntaxe):
Il s'agit d'une erreur de syntaxe , car, lorsqu'elle est utilisée avec
inner join
, les fonctions de table ne peuvent accepter que des variables ou des constantes comme paramètres. (C'est-à-dire que le paramètre de fonction de table ne peut pas dépendre de la colonne d'une autre table.)Toutefois:
C'est légal.
Edit: Ou bien, une syntaxe plus courte: (par ErikE)
Éditer:
Remarque: Informix 12.10 xC2 + a des tableaux dérivés latéraux et Postgresql (9.3+) a des sous-requêtes latérales qui peuvent être utilisées pour un effet similaire.
la source
SELECT
besoin à l'intérieur duCROSS APPLY
. Veuillez essayerCROSS APPLY dbo.myTableFun(O.name) F
.Considérez que vous avez deux tables.
TABLE MAÎTRE
TABLEAU DE DÉTAILS
Il existe de nombreuses situations où nous devons remplacer
INNER JOIN
avecCROSS APPLY
.1. Joignez deux tableaux en fonction des
TOP n
résultatsConsidérez si nous devons choisir
Id
etName
deMaster
et deux dates pour chacunId
deDetails table
.La requête ci-dessus génère le résultat suivant.
Voir, il a généré des résultats pour les deux dernières dates avec les deux dernières dates,
Id
puis n'a joint ces enregistrements que dans la requête externeId
, ce qui est faux. Cela devrait renvoyer à la foisIds
1 et 2 mais il n'a renvoyé que 1 car 1 a les deux dernières dates. Pour ce faire, nous devons utiliserCROSS APPLY
.et forme le résultat suivant.
Voici comment ça fonctionne. La requête à l'intérieur
CROSS APPLY
peut référencer la table externe, oùINNER JOIN
ne peut pas le faire (elle génère une erreur de compilation). Lors de la recherche des deux dernières dates, la jonction se fait à l'intérieur,CROSS APPLY
c'est- à- direWHERE M.ID=D.ID
.2. Lorsque nous avons besoin de
INNER JOIN
fonctionnalités utilisant des fonctions.CROSS APPLY
peut être utilisé en remplacementINNER JOIN
lorsque nous devons obtenir le résultat duMaster
tableau et afunction
.Et voici la fonction
qui a généré le résultat suivant
AVANTAGE SUPPLÉMENTAIRE DE L'APPLICATION CROISÉE
APPLY
peut être utilisé en remplacement deUNPIVOT
. SoitCROSS APPLY
ouOUTER APPLY
peut être utilisé ici, qui sont interchangeables.Considérez que vous avez le tableau ci-dessous (nommé
MYTABLE
).La requête est ci-dessous.
qui vous apporte le résultat
la source
Il me semble que CROSS APPLY peut combler une certaine lacune lorsque vous travaillez avec des champs calculés dans des requêtes complexes / imbriquées, et les rendre plus simples et plus lisibles.
Exemple simple: vous avez un DoB et vous souhaitez présenter plusieurs champs liés à l'âge qui s'appuieront également sur d'autres sources de données (telles que l'emploi), comme Age, AgeGroup, AgeAtHiring, MinimumRetirementDate, etc. pour une utilisation dans votre application d'utilisateur final (Excel PivotTables, par exemple).
Les options sont limitées et rarement élégantes:
Les sous-requêtes JOIN ne peuvent pas introduire de nouvelles valeurs dans l'ensemble de données sur la base des données de la requête parent (elles doivent être autonomes).
Les FDU sont soignés, mais lents car ils ont tendance à empêcher les opérations parallèles. Et être une entité distincte peut être une bonne chose (moins de code) ou une mauvaise chose (où est le code).
Tables de jonction. Parfois, ils peuvent fonctionner, mais assez tôt, vous rejoignez des sous-requêtes avec des tonnes d'UNIONS. Grand désordre.
Créez une autre vue à usage unique, en supposant que vos calculs ne nécessitent pas de données obtenues à mi-chemin de votre requête principale.
Tables intermédiaires. Oui ... cela fonctionne généralement, et souvent une bonne option car ils peuvent être indexés et rapides, mais les performances peuvent également baisser car les instructions UPDATE ne sont pas parallèles et ne permettent pas de mettre en cascade des formules (réutiliser les résultats) pour mettre à jour plusieurs champs dans le même déclaration. Et parfois, vous préférez simplement faire les choses en un seul passage.
Imbrication de requêtes. Oui, à tout moment, vous pouvez mettre des parenthèses sur l'ensemble de votre requête et l'utiliser comme sous-requête sur laquelle vous pouvez manipuler les données source et les champs calculés. Mais vous ne pouvez pas faire ça avant que ça ne devienne laid. Très laid.
Code répétitif. Quelle est la plus grande valeur de 3 instructions longues (CASE ... ELSE ... END)? Ça va être lisible!
Ai-je oublié quelque chose? Probablement, alors n'hésitez pas à commenter. Mais bon, CROSS APPLY est comme une aubaine dans de telles situations: il suffit d'ajouter un simple
CROSS APPLY (select tbl.value + 1 as someFormula) as crossTbl
et voilà! Votre nouveau champ est maintenant prêt à être utilisé pratiquement comme il l'avait toujours été dans vos données source.Les valeurs introduites via CROSS APPLY peuvent ...
CROSS APPLY (select crossTbl.someFormula + 1 as someMoreFormula) as crossTbl2
Dang, ils ne peuvent rien faire!
la source
L'application croisée fonctionne également bien avec un champ XML. Si vous souhaitez sélectionner des valeurs de nœud en combinaison avec d'autres champs.
Par exemple, si vous avez une table contenant du xml
Utilisation de la requête
Renvoie un résultat
la source
Cela a déjà été très bien répondu techniquement, mais permettez-moi de donner un exemple concret de la façon dont il est extrêmement utile:
Disons que vous avez deux tables, Client et Commande. Les clients ont de nombreuses commandes.
Je veux créer une vue qui me donne des détails sur les clients et la dernière commande qu'ils ont passée. Avec juste JOINS, cela nécessiterait quelques auto-jointures et agrégation, ce qui n'est pas joli. Mais avec Cross Apply, c'est super simple:
la source
L'application croisée peut être utilisée pour remplacer la sous-requête lorsque vous avez besoin d'une colonne de la sous-requête
sous-requête
ici, je ne pourrai pas sélectionner les colonnes du tableau de la société, donc, en utilisant l'application croisée
la source
Je suppose que ça devrait être la lisibilité;)
CROSS APPLY sera quelque peu unique pour les personnes qui lisent pour leur dire qu'un UDF est utilisé qui sera appliqué à chaque ligne du tableau de gauche.
Bien sûr, il existe d'autres limitations lorsqu'un CROSS APPLY est mieux utilisé que JOIN que d'autres amis ont posté ci-dessus.
la source
Voici un article qui explique tout, avec leur différence de performances et leur utilisation sur JOINS.
SQL Server CROSS APPLY et OUTER APPLY over JOINS
Comme suggéré dans cet article, il n'y a aucune différence de performances entre eux pour les opérations de jointure normales (INNER ET CROSS).
La différence d'utilisation survient lorsque vous devez effectuer une requête comme celle-ci:
Autrement dit, lorsque vous devez vous rapporter à la fonction. Cela ne peut pas être fait en utilisant INNER JOIN, ce qui vous donnerait l'erreur "L'identifiant en plusieurs parties" D.DepartmentID "n'a pas pu être lié." Ici, la valeur est transmise à la fonction lors de la lecture de chaque ligne. Ça me semble cool. :)
la source
Eh bien, je ne sais pas si cela peut être considéré comme une raison d'utiliser l'application croisée par opposition à la jointure interne, mais cette question a été répondue pour moi dans un message sur le forum à l'aide de l'application croisée, donc je ne suis pas sûr s'il existe une méthode équivalente utilisant la jointure interne:
COMME COMMENCER
FIN
la source
L'essence de l'opérateur APPLY est de permettre la corrélation entre le côté gauche et le côté droit de l'opérateur dans la clause FROM.
Contrairement à JOIN, la corrélation entre les entrées n'est pas autorisée.
En parlant de corrélation dans l'opérateur APPLY, je veux dire sur le côté droit, nous pouvons mettre:
Les deux peuvent renvoyer plusieurs colonnes et lignes.
la source
C'est peut-être une vieille question, mais j'aime toujours la puissance de CROSS APPLY pour simplifier la réutilisation de la logique et pour fournir un mécanisme de "chaînage" des résultats.
J'ai fourni un SQL Fiddle ci-dessous qui montre un exemple simple de la façon dont vous pouvez utiliser CROSS APPLY pour effectuer des opérations logiques complexes sur votre ensemble de données sans que les choses deviennent du tout compliquées. Il n'est pas difficile d'extrapoler à partir d'ici des calculs plus complexes.
http://sqlfiddle.com/#!3/23862/2
la source
Alors que la plupart des requêtes qui utilisent CROSS APPLY peuvent être réécrites à l'aide d'un INNER JOIN, CROSS APPLY peut fournir un meilleur plan d'exécution et de meilleures performances, car il peut limiter l'ensemble à joindre avant que la jointure ne se produise.
Volé d' ici
la source