REJOIGNEZ rapport EXISTE performance
De manière générale, il y a une différence de performance entre l'aide d'une JOINTURE pour sélectionner les lignes par rapport à une EXISTE clause where? Recherche de diverses Q&Un des sites web suggère qu'une jointure est plus efficace, mais je me souviens d'apprentissage il y a longtemps ce qui EXISTE a été de mieux en Teradata.
Je vois les autres, de SORTE réponses, comme cette et cette, mais ma question est spécifique à Teradata.
Par exemple, tenir compte de ces deux requêtes qui retournent des résultats identiques:
select svc.ltv_scr, count(*) as freq
from MY_BASE_TABLE svc
join MY_TARGET_TABLE x
on x.srv_accs_id=svc.srv_accs_id
group by 1
order by 1
-et-
select svc.ltv_scr, count(*) as freq
from MY_BASE_TABLE svc
where exists(
select 1
from MY_TARGET_TABLE x
where x.srv_accs_id=svc.srv_accs_id)
group by 1
order by 1
De l'index principal (unique) sur les deux tables 'srv_accs_id'. MY_BASE_TABLE est plutôt grand (200 millions de lignes) et MY_TARGET_TABLE relativement faible (200 000 lignes).
Il y a une différence significative dans les plans d'explication: La première indique que les deux tables sont jointes "par le moyen d'un RowHash match scan" et le deuxième dit "par le moyen de lignes de balayage". Autant vous dire qu'elle est "un des Amplis de REJOINDRE l'étape" et le temps total estimé est identique (de 0,32 secondes).
Les deux requêtes effectuer la même chose (je suis en utilisant Teradata 13.10).
Une expérience similaire de trouver des non-correspond à la comparaison d'une JOINTURE EXTERNE GAUCHE avec une correspondante EST NULLE la clause where d'une n'EXISTE PAS de sous-requête ne montrent une différence de performance:
select svc.ltv_scr, count(*) as freq
from MY_BASE_TABLE svc
left outer join MY_TARGET_TABLE x
on x.srv_accs_id=svc.srv_accs_id
where x.srv_accs_id is null
group by 1
order by 1
-et-
select svc.ltv_scr, count(*) as freq
from MY_BASE_TABLE svc
where not exists(
select 1
from MY_TARGET_TABLE x
where x.srv_accs_id=svc.srv_accs_id)
group by 1
order by 1
Le second plan de requête est plus rapide (2.21 contre 2.14 secondes, comme décrit par EXPLIQUER).
Mon exemple est peut-être trop banal pour voir une différence; je suis simplement à la recherche pour le codage de l'orientation.
Oui, je me rends compte que, je suis juste essayé de faire un exemple pour illustrer ma question. Aussi, je me suis juste assis à travers une Teradata présentation sur
EXPLAIN
et ont appris que ceux qui sont relatifs "coût" des estimations et n'ont rien à voir avec le "temps".
OriginalL'auteur BellevueBob | 2012-12-03
Vous devez vous connecter pour publier un commentaire.
N'EXISTE PAS est plus efficace que l'utilisation d'une JOINTURE EXTERNE GAUCHE pour exclure les documents manquants à partir de la participation de la table à l'aide d'une EST NULLE en l'état car l'optimiseur va choisir d'utiliser une EXCLUSION de JOINTURE de FUSION avec la n'EXISTE PAS de prédicat.
Pendant que votre deuxième test ne permettait pas d'obtenir des résultats impressionnants pour les ensembles de données que vous utilisez l'augmentation de la performance à partir de n'EXISTE PAS sur une JOINTURE GAUCHE est très perceptible pour vos volumes de données augmentent. Gardez à l'esprit que les tables devront être de hachage distribuée par les colonnes qui participent à la n'EXISTE PAS rejoindre tout comme ils le feraient dans la JOINTURE GAUCHE. Par conséquent, l'altération de données peut affecter les performances de l'EXCLUSION de JOINTURE de FUSION.
EDIT:
Généralement, je voudrais reporter à exister comme un remplacement pour DANS au lieu de l'utiliser pour la ré-écriture d'une jointure solution. Cela est particulièrement vrai lorsque la colonne(s) en participant à la logique de comparaison peut être NULL. Cela ne veut pas dire que vous ne pouvez pas utiliser EXISTE à la place d'une JOINTURE INTERNE. Au lieu d'une EXCLUSION REJOINDRE, vous vous retrouverez avec une INCLUSION de JOINTURE. La JOINTURE INTERNE est, par essence, une inclusion rejoindre pour commencer. Je suis sûr qu'il ya des nuances que je suis dominant, mais tu peux les trouver dans les manuels si vous souhaitez prendre le temps de les lire.
LEFT OUTER JOIN
. Aucun commentaire sur la première partie (JOIN
contreEXISTS
)?Personnellement , je pense que c'est une bien mauvaise réponse. Tout sain d'analyser la requête permettrait de détecter les anti-jointure. (si il y aurait une différence de timing, le plan de générateur serait très mal). btw: dans l'ancien temps, "n'existe pas" serait toujours plus vite, juste parce qu'il est venu en premier, et les autres variantes (mais équivalent) serait moins bon. Le "JOIN...NULL" la forme est relativement nouveau. La DANS la variante a toujours été un perdant, car les doublons doivent être évitées par la sous-requête (à l'exception de la valeur NULL problème)
Merci pour la clarification de ma réponse @wildplasser. (D'où le upvote sur votre commentaire.) J'ai omis de parler de l'impact que les doublons pourraient présenter lors de l'utilisation de la
IN
clause et le fait queNOT EXISTS
est antérieure à l'utilisation deJOIN ... NULL
dans le lexique SQL.Il y a un autre "homme", l'avantage EXISTE syntaxe: il n'est pas polluer la requête externe avec ses rangetable (mais, étant une sous-requête corrélée, il ne avoir à se référer à la requête externe, bien sûr) Cela fait
SELECT * FROM a WHERE EXISTS (SELECT * FROM B where b.xx= a.yy)
possible; Leselect *
serait autrement contiennent la totalité de l'rangetable, y compris les noms dupliqués pour les colonnes jointes.OriginalL'auteur Rob Paller