Почему этот SQL-запрос приводит к сканированию индекса, а не к поиску индекса? - PullRequest
5 голосов
/ 29 января 2011

Может кто-нибудь помочь мне настроить этот 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')

.

Вот как выглядит План выполнения:

.

enter image description here

Чего я не понимаю, так это почему я получаю индексное сканирование для заявителей NP. У меня есть индекс, который охватывает BuildingID и ApartmentID. Разве это не должно быть использовано?

Ответы [ 2 ]

6 голосов
/ 29 января 2011

Это потому, что он ожидает около 10K записей, чтобы вернуться из матчей. Возвращение к данным для извлечения других столбцов с использованием ключей 10 КБ эквивалентно производительности простого сканирования 100 КБ записей (как минимум) и фильтрации с использованием хеш-совпадения.

Что касается доступа к другой таблице, Оптимизатор запросов решил, что ваш индекс полезен (вероятно, для Offline или MA), поэтому он ищет по этому индексу, чтобы получить ключи объединения.

Затем эти два сопоставляются с HASH для пересечений для получения окончательного результата.

3 голосов
/ 29 января 2011

Поиск по индексу B-Tree в несколько раз дороже сканирования таблицы (для каждой записи).

Кроме того, необходимо выполнить другой поиск в кластеризованном индексе для получения значений других столбцов.

Если ожидается, что большая часть записей будет соответствовать, дешевле сканировать кластерный индекс.

Чтобы убедиться, что оптимизатор выбрал лучший метод, вы можете запустить это:

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')

Замените index_name фактическим именем вашего индекса и сравните время выполнения и количество операций I/O (как видно на вкладке сообщений)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...