Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Pourquoi s'agit-il d'un balayage d'index et non d'une recherche d'index ?

Il utilise une analyse d'index principalement parce qu'il utilise également une jointure par fusion. L'opérateur Merge Join nécessite deux flux d'entrée triés dans un ordre compatible avec les conditions Join.

Et il utilise l'opérateur Merge Join pour réaliser votre INNER JOIN car il pense que cela sera plus rapide que l'opérateur Nested Loop Join plus typique. Et c'est probablement vrai (c'est généralement le cas), en utilisant les deux index qu'il a choisis, il a des flux d'entrée qui sont tous deux pré-triés en fonction de votre condition de jointure (LocationID). Lorsque les flux d'entrée sont pré-triés de cette manière, les jointures de fusion sont presque toujours plus rapides que les deux autres (jointures de boucle et de hachage).

L'inconvénient est ce que vous avez remarqué :il semble scanner l'intégralité de l'index, alors comment cela peut-il être plus rapide s'il lit autant d'enregistrements qui ne seront peut-être jamais utilisés ? La réponse est que les scans (en raison de leur nature séquentielle) peuvent lire entre 10 et 100 fois plus d'enregistrements/seconde que de recherches.

Maintenant, les recherches gagnent généralement parce qu'elles sont sélectives :elles n'obtiennent que les lignes que vous demandez, tandis que les analyses sont non sélectives :elles doivent renvoyer chaque ligne de la plage. Mais parce que les scans ont beaucoup un taux de lecture plus élevé, ils peuvent fréquemment battre Seeks tant que le rapport entre les lignes supprimées et les lignes correspondantes est inférieur que le ratio de Scan rows/sec VS. Recherche lignes/sec.

Des questions ?

OK, on ​​m'a demandé d'expliquer davantage la dernière phrase :

Une "ligne ignorée" est une ligne que le scan lit (car il doit tout lire dans l'index), mais qui sera rejetée par l'opérateur Merge Join, car il n'y a pas de correspondance de l'autre côté, peut-être parce que le La condition de la clause WHERE l'a déjà exclu.

Les "lignes correspondantes" sont celles qu'il a lues et qui correspondent réellement à quelque chose dans la jointure de fusion. Ce sont les mêmes lignes qui auraient été lues par un Seek si le Scan avait été remplacé par un Seek.

Vous pouvez comprendre ce qu'il y a en regardant les statistiques dans le plan de requête. Vous voyez cette énorme grosse flèche à gauche de l'index scan ? Cela représente le nombre de lignes que l'optimiseur pense lire avec l'analyse. La boîte de statistiques de l'analyse d'index que vous avez publiée montre que les lignes réelles renvoyées sont d'environ 5,4 millions (5 394 402). Ceci est égal à :

TotalScanRows = (MatchingRows + DiscardedRows)

(Dans mes termes, en tout cas). Pour obtenir les lignes correspondantes, regardez les "lignes réelles" signalées par l'opérateur Merge Join (vous devrez peut-être supprimer le TOP 100 pour obtenir cela avec précision). Une fois que vous savez cela, vous pouvez obtenir les lignes rejetées en :

DiscardedRows = (TotalScanRows - MatchingRows)

Et maintenant, vous pouvez calculer le ratio.