" L'opérateur est très lent que "=" sur la table avec quelques millions de lignes - Retrouvez les réponses et les commentaires concernant cette question" />
10
votes

SQL Server "<>" L'opérateur est très lent que "=" sur la table avec quelques millions de lignes

J'ai deux tables. Les formulaires ont ~ 77000 rangées. Les journaux ont ~ 2,7 millions de lignes.

La requête suivante revient "30198" en moins d'une seconde: xxx

et cette requête est en cours d'exécution depuis environ 15 minutes. et n'a toujours pas fini: xxx

pourquoi est la requête "non égale" si beaucoup plus lente?


3 commentaires

Qu'en est-il de où pas logiciel logs.docid = formes.docid ?


Essayez-vous de trouver des valeurs logs.docid pour lesquelles aucune valeur correspondante n'existe dans formulaires ? Si c'est le cas, essayez SELECT Count (*) à partir de (sélectionnez DOCID à partir des journaux, sauf sélectionnez DOCID dans Formulaires) T


@Martin - Votre requête est revenue en 8 secondes. Merci!


3 Réponses :


29
votes

parce que = code> réduit l'opération de jointure à une seule ligne correspondante de chaque table (présumer que ces docidaires sont uniques).

pense de cette façon - vous avez une danse avec 5 garçons et 5 filles: p> xxx pré>

vous les associez par première lettre. Donc p> xxx pré>

un seul couplage p>

Mais si vous les associez par "premières lettres ne correspond pas", vous vous retrouvez avec: p>

SELECT DISTINCT logs.DOCID
FROM logs
LEFT JOIN forms ON logs.DOCID = forms.DOCID
WHERE forms.DOCID IS NULL


10 commentaires

+1 Je suppose que l'OP a probablement besoin pas dans ou n'existe pas ou sauf


Merci! Je ne peux rien faire pour optimiser ma requête? Je cherche des formidés dans la table des journaux qui ne correspondent pas aux formidés dans la table des formulaires. Je pense que je connais la réponse en trouvant le delta de comptage (logogide distinct) et comptez (logogides distincts) où logs.formid = formes.formid


Sélectionnez Count (*) à partir de (sélectionnez DOCID à partir de journaux sauf sélectionnez DOCID dans les formulaires) T


@MARC - RE: Votre édition. C'est la manière la moins efficace de faire une jointure anti-semi dans SQL Server. lien 1 , LINK 2


@Martin Smith - avec un groupe distinct ou un groupe sur les deux requêtes internes (l'OP a compte (distinct) donc je suppose que ce ne sont pas des champs uniques ...)


Merci a tous. Cela m'aide à mieux comprendre SQL un peu mieux. Sélectionnez Compte (logs distincts) à partir de journaux, formidez où logs.docid pas dans (sélectionnez Forms.docide des formulaires); est retourné en 11 secondes. @Martin Smith - Sélectionnez Count (*) à partir de (Sélectionnez DOCID à partir de journaux, sauf sélectionnez DOCID à partir de formulaires) T; Retourné en 8 secondes.


@Dems - sauf supprime les doublons


@Tredman une suggestion, même si vous irez probablement avec Martin's sauf Suggestion - N'utilisez pas pas dans à moins que vous n'êtes absolument certain à 100% de la colonne de l'intérieur ne peut pas être null . n'existe pas est généralement préférable sur pas dans .


@Tredman - Je fortement vous recommande d'arrêter d'utiliser la notation , . Le code dans votre commentaire ci-dessus fait cela ... Prenez la table , exclure chaque enregistrement où il est docide n'est pas dans les formulaires < / Code> Tableau, puis rejoignez chaque enregistrement restant contre l'intégralité des formulaires . (77000 matchs par enregistrement, un produit croisé, et je suis sûr que vous ne l'entendiez pas)


@Dems, je devrai m'habituer à cette ... Sélectionnez Compte (distinct L.DOCID) à partir de journaux L Formulaires de jointure intérieure F Formulaires F sur F.DOCID = L.DOCID;



2
votes

Deux raisons:

  • Les requêtes d'équivalence peuvent généralement utiliser des index (si disponibles), tandis que la requête pour la non-comparaison ne peut pas

  • <> retourne tellement plus de données.

    Votre requête avec <> est faux. Que devrait-il retourner?


2 commentaires

Merci pour la réponse. Il devrait retourner ~ 3800. Je cherche des formidés dans la table des journaux qui ne correspondent pas aux formidés dans la table des formulaires. Quelqu'un d'autre a répondu ci-dessus - je devrais utiliser Existe ou dans .


Oui. Une autre possibilité serait la jointure extérieure droite avec est null .



1
votes

Ceci est totalement dépendant de la distribution de valeurs dans le tableau. Si la colonne que vous recherchez, par exemple, avait la même valeur (= formulaires.docide) pour 99,99% des lignes et une seule ligne avec une valeur différente, vous verriez exactement le comportement opposé.


0 commentaires