0

У меня есть некластеризованный индекс в столбце datetime (AdmitDate) и столбец varchar (Status) в SQL Server. Теперь проблема в том, что я фильтрую результат только на основе столбца datetime (без индекса в столбце AdmitDate).Некластеризованный индексный указатель на составной столбец

Для того чтобы я использовал некластеризованный индекс, я использовал условие не null для столбца varchar (Status), но в этом случае в плане выполнения отображается «Сканирование индекса».

select ClientName, ID 
from PatientVisit 
where 
    (PatientVisit.AdmitDate between '2010-01-01 00:00:00.000' AND '2014-01-31 00:00:00.000') 
    AND PatientVisit.Status is not null 

-- Index Scan 

Но если я передаю конкретное значение статуса, то, как и ожидалось, в плане выплат отображается Index Seek.

select ClientName, ID 
from PatientVisit 
where 
    (PatientVisit.AdmitDate between '2010-01-01 00:00:00.000' AND '2014-01-31 00:00:00.000') 
    AND PatientVisit.Status = 'ADM' 

--Index Seek 

Должен ли я использовать в операторе и передать все возможные значения для Status колонки использовать не-кластерный индекс?

Или есть ли другой способ использования индекса?

Спасибо,

Shubham

+1

Вы указываете: * У меня есть кластерный указатель на столбце datetime (AdmitDate) * и: * Нет индекса в столбце AdmitDate *. Какое из двух истинно? –

+1

Можете ли вы показать нам, как именно вы создаете этот индекс? Каков порядок столбцов в индексе? –

+0

Также: я уверен, что индекс Index Seek находится на вашем фактическом некластеризованном индексе, тогда как «Index Scan» находится в кластерном индексе (например, сама таблица) - правильно? –

ответ

0

Создать filtered index. Затем вы можете создать индекс для поля datetime только для значений, где статус не равен нулю.

CREATE NONCLUSTERED INDEX FI_IX_AdmitDate_StatusNotNull 
    ON dbo.PatientVisit(AdmitDate) 
    WHERE Status IS NOT NULL 

Это будет использоваться для запроса, где Status IS NOT NULL и существующий индекс будет использоваться для запросов, где Status = 'ASpecificValue'

1

Вы с помощью SELECT ClientID, Name и вы запрашиваете столбцы, которые не являются частью индекса, SQL Server необходимо будет перейти на фактическую страницу данных, чтобы получить эти значения столбцов.

Так что если SQL Server найдет совпадение в некластеризованном индексе, он должен будет сделать (дорогой) поиск ключей в кластерный индекс, чтобы получить страницу данных, содержащую все столбцы.

Если слишком много строк имеют Status, то есть NULL, SQL Server придет к выводу, что быстрее всего просто кровавый сканирование всего индекса, а затем выполняется большое количество запросов индекса и ключевых поисков. В другом случае, когда вы определяете конкретное значение и которое соответствует только нескольким (или только одному) строкам, тогда может быть быстрее фактически искать индекс и один дорогой поиск ключа.

Вы, что вы могли попробовать это использовать индекс, который включает эти две колонки, которые вам нужны для SELECT:

CREATE NONCLUSTERED INDEX IX_PatientVisit_DateStatusIncluded 
ON dbo.PatientVisit(AdmitDate, Status) 
INCLUDE(ClientID, Name) 

Теперь в этом случае SQL Server может найти значения, которые необходимы до удовлетворить этот запрос на странице листа индекса, так что на самом деле будет более вероятно на самом деле использовать этот индекс - даже если он находит много хитов - возможно, с помощью Index Scan на этом mall index (что тоже неплохо!)

Смежные вопросы