Pourquoi ce résultat SQL dans Index Scan au lieu d'un index Seek?

Est-ce que quelqu'un peut m'aider s'il vous plaît à régler cette requête SQL?

SELECT a.BuildingID, a.ApplicantID, a.ACH, a.Address, a.Age, a.AgentID, a.AmenityFee, a.ApartmentID, a.Applied, a.AptStatus, a.BikeLocation, a.BikeRent, a.Children, a.CurrentResidence, a.Email, a.Employer, a.FamilyStatus, a.HCMembers, a.HCPayment, a.Income, a.Industry, a.Name, a.OccupancyTimeframe, a.OnSiteID, a.Other, a.ParkingFee, a.Pets, a.PetFee, a.Phone, a.Source, a.StorageLocation, a.StorageRent, a.TenantSigned, a.WasherDryer, a.WasherRent, a.WorkLocation, a.WorkPhone, a.CreationDate, a.CreatedBy, a.LastUpdated, a.UpdatedBy FROM dbo.NPapplicants AS a INNER JOIN dbo.NPapartments AS apt ON a.BuildingID = apt.BuildingID AND a.ApartmentID = apt.ApartmentID WHERE (apt.Offline = 0) AND (apt.MA = 'M') 

.

Voici à quoi ressemble le plan d'exécution:

.

entrez la description de l'image ici

Ce que je ne comprends pas, c'est pourquoi je reçois un index scan pour NPapplicants. J'ai un index qui couvre BuildingID et ApartmentID. Ne devrait-il pas être utilisé?

C'est parce qu'il s'attend à ce que près de 10 000 loggings reviennent des matchs. Revenir aux données pour récupérer d'autres colonnes en utilisant des keys 10K équivaut à quelque chose comme la performance de simplement scanner des loggings 100K (au minimum) et filterr en utilisant la concordance de hachage.

En ce qui concerne l'access à l'autre table, l'Optimiseur de requêtes a décidé que votre index est utile (probablement par rapport à Offline ou MA ), donc il cherche sur cet index pour get les keys de jointure.

Ces deux sont ensuite appariés HASH pour les intersections afin de produire la sortie finale.

Une search dans un index B-Tree est plusieurs fois plus coûteuse qu'une parsing de table (par logging).

En outre, une autre search dans l'index cluster doit être effectuée pour récupérer les valeurs des autres colonnes.

Si une grande partie des loggings est censée correspondre, il est less coûteux d'parsingr l'index clusterisé.

Pour vous assurer que l'optimiseur a choisi la meilleure méthode, vous pouvez exécuter ceci:

 SET STATISTICS IO ON SET STATSTICS TIME ON SELECT a.BuildingID, a.ApplicantID, a.ACH, a.Address, a.Age, a.AgentID, a.AmenityFee, a.ApartmentID, a.Applied, a.AptStatus, a.BikeLocation, a.BikeRent, a.Children, a.CurrentResidence, a.Email, a.Employer, a.FamilyStatus, a.HCMembers, a.HCPayment, a.Income, a.Industry, a.Name, a.OccupancyTimeframe, a.OnSiteID, a.Other, a.ParkingFee, a.Pets, a.PetFee, a.Phone, a.Source, a.StorageLocation, a.StorageRent, a.TenantSigned, a.WasherDryer, a.WasherRent, a.WorkLocation, a.WorkPhone, a.CreationDate, a.CreatedBy, a.LastUpdated, a.UpdatedBy FROM dbo.NPapplicants AS a INNER JOIN dbo.NPapartments AS apt ON a.BuildingID = apt.BuildingID AND a.ApartmentID = apt.ApartmentID WHERE (apt.Offline = 0) AND (apt.MA = 'M') SELECT a.BuildingID, a.ApplicantID, a.ACH, a.Address, a.Age, a.AgentID, a.AmenityFee, a.ApartmentID, a.Applied, a.AptStatus, a.BikeLocation, a.BikeRent, a.Children, a.CurrentResidence, a.Email, a.Employer, a.FamilyStatus, a.HCMembers, a.HCPayment, a.Income, a.Industry, a.Name, a.OccupancyTimeframe, a.OnSiteID, a.Other, a.ParkingFee, a.Pets, a.PetFee, a.Phone, a.Source, a.StorageLocation, a.StorageRent, a.TenantSigned, a.WasherDryer, a.WasherRent, a.WorkLocation, a.WorkPhone, a.CreationDate, a.CreatedBy, a.LastUpdated, a.UpdatedBy FROM dbo.NPapplicants WITH (INDEX (index_name)) AS a INNER JOIN dbo.NPapartments AS apt ON a.BuildingID = apt.BuildingID AND a.ApartmentID = apt.ApartmentID WHERE (apt.Offline = 0) AND (apt.MA = 'M') 

Remplacez index_name par le nom réel de votre index et comparez les durées d'exécution et les nombres d'opérations d' I/O (comme dans l'onglet des messages)