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.

Ne réaliser que le premier ensemble de requêtes (EXISTE) extrait .1% des lignes, la deuxième série (n'EXISTE PAS) va chercher à 99,9% des lignes. En termes de nombre de pages extraites, la première requête peut utiliser un indice de minimiser le nombre de page extrait, dans la seconde efficacement tous pages seront nécessaires. C'est pourquoi le planificateur choisit pour numériser toutes les pages dans le second cas. La différence entre left join ... NULL et PAS n'a pas l'air trop important pour moi. (commande? cache amorçage?) Avertissement: je ne sais pas teradata.
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