0
votes

Performance - Sélectionnez Requête avec la jointure gauche et la vérification null

J'ai deux tables différentes appelées en tant que traitement (enregistrements de 30 m pour l'instant) code> et eTlrecord (4,3 m enregistrements pour l'instant) code>. Comme le nom des tables suggèrent, ces tables seront utilisées pour la normalisation des données avec ETL.

Nous essayons de traiter des enregistrements avec des lots où nous avons 1000 enregistrements dans chaque lot. P>

SELECT TOP 1000 P.StreamGuid
FROM [staging].[Processing] P           (NOLOCK)
LEFT JOIN [core].[EtlRecord] E          (NOLOCK)    ON E.StreamGuid = P.StreamGuid
WHERE E.StreamGuid IS NULL
AND P.CompleteDate IS NOT NULL
AND P.StreamGuid IS NOT NULL


7 commentaires

Changer en n'existe pas de sorte qu'il ne jointe pas à toutes les lignes, puis filtrez toutes les personnes sauf les autres que e.streamguid est null - cela pourrait ne pas résoudre tout votre Les émissions comme les boucles imbriquées pourraient être le principal problème, mais essayez-le en premier. Si vous utilisez toujours des problèmes, essayez Utiliser un indice («désactiver_optimizer_rowogoal») pour voir si cela aide


Merci pour votre temps, j'ai testé n'existe pas mais le plan d'exécution était exactement le même. Donc, il n'y a pas d'amélioration de la performance. En outre, à cause de ma version SQL Server, je ne peux pas utiliser désactiver_optimizer_rowgoal indice.


Pourquoi importaient-vous une table de 30 m enregistrements 1000 enregistrements à la fois? S'il faut 20 secondes pour exécuter votre flux de travail pour 1000 enregistrements, vous recherchez 7 jours pour traiter toutes les lignes de 30 m.


Le plan d'exécution ne sera pas exactement le même. Ce sera une jointure anti-semi. Pas un jointure extérieure et filtrer. En ce qui concerne l'objectif de ligne, vous pouvez paramétrer le top optimiser pour un grand nombre mais passe dans 1000 pour atteindre beaucoup de même


déclarer @top int = 1000 Sélectionnez le dessus (@top) P.Streamguid de [Stalage]. [Traitement] P. [Traitement] P où n'existe pas (sélectionnez * à partir de [eTlrecord] E Où e.streamguid = p.streamguid ) Et P.Streamguid ne sont pas une option NULL (optimiser pour (@top = 0x7FFFFFF)) et un index filtré permettant au p. index permettant à P. code> p. p.S.Complet n'est pas null et p.streamguid est Non null prédicats à résoudre efficacement pourrait être utile


J'ai essayé votre solution, cela a travaillé comme un charme. Merci beaucoup @martinsmith. Appromaxily, c'est environ 5 secondes maintenant, parfois moins que cela. Mais je crois en long terme lorsque les données continuent à augmenter, je pourrais retrouver la même question de performance. Je prévois donc de changer ma mise en œuvre. Je prévois de débarrasser du malidentifiant et de le remplacer par Bigint. Je peux donc garder le dernier enregistrement traité dans la session et récupérer le lot suivant sans vérifier les données dans la table d'Etlrecord.


@Martinsmith pouvez-vous mettre votre commentaire comme une réponse afin que je puisse la marquer comme réponse acceptée


3 Réponses :


1
votes

Eh bien, dans votre requête, vous devez obtenir des enregistrements de [stadification]. [Traitement] code> qui n'a pas reçu l'enregistrement correspondant dans le [noyau]. [Etlrecord] code> .

Vous pouvez enlever les enregistrements précédents, en premier. P>

WHERE CompleteDate IS NOT NULL
    AND StreamGuid IS NOT NULL;


1 commentaires

Merci pour votre temps mais malheureusement, cela ne fonctionnera pas dans mon cas. Nous avons créé un tableau eTlrecord pour éviter le verrouillage de la table lors de l'insertion d'enregistrement sur Traitement Tableau. Également essayé de définir l'index filtré, mais cela n'a pas fonctionné aussi bien. Après tout, le champ NULL appartient au résultat pour ne pas table lui-même.



1
votes

Les données d'échantillons de DDL et de consommables DDL et facilement consommables, comme ci-dessous, vous aideront beaucoup. Vous pouvez copier / coller mes solutions et les exécuter localement pour voir de quoi je parle.

CREATE NONCLUSTERED INDEX nc_processing ON #processing(CompleteDate,StreamGuid)
    WHERE CompleteDate IS NOT NULL;


3 commentaires

Merci pour votre temps en rejouer la question. Mais comme j'ai déjà commenté @gotqn réponse, l'indice filtré ne fonctionnera pas dans mon cas. Je n'essaie pas de filtrer les registres NULL dans la table d'Etlrecord, j'essaie d'obtenir 1000 enregistrements suivants qui ne sont pas sorties dans la table d'Etlrecord à partir de la table de traitement.


@Serdar - Les lignes de la table de traitement qui ne respectent pas p.CharteDate n'est pas null et p.streamguid n'est pas null Ne devez pas être lu ou participer à la jointure, voilà comment le filtrage L'index peut aider


@Serdar Désolé, j'ai raté votre commentaire sous ce que Publié Gotnn.



0
votes

Je suggérerais d'écrire ceci comme suit: xxx

i supprimé la directive nolock . Utilisez-le seulement si vous savez vraiment ce que vous faites - et êtes prêt à lire des données non valides.

alors vous voulez absolument un index sur eTlrecord (streamguid)

Vous voulez probablement aussi un index sur le traitement (counteal, streamuid) . Ceci est au moins un indice de couverture pour la requête.


0 commentaires