Когда SQL Server выбирает сканирование индекса? - PullRequest
0 голосов
/ 30 марта 2012
select 
    a.Transport_Mode, sum(a.Inv_Qty)
from 
    dbo.DespSum_Year a, dbo.Item_Master b
where 
    a.Inv_Date between '2011-04-01' and '2012-03-31'
    and a.item_name = b.itemcode
group by 
    a.Transport_Mode

У меня есть 10 миллионов строк в despsum_year и некластеризованный индекс в Inv_date.

Когда я выполняю вышеуказанный запрос, он показывает его использование сканирования таблицы.Может кто-нибудь сказать мне, как сделать запрос с помощью сканирования индекса?

Ответы [ 2 ]

2 голосов
/ 30 марта 2012

Ваш запрос состоит из трех частей, для которых требуется отсортированная таблица.
1. JOIN
2. Предложение WHERE
3. GROUP BY

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

Я бы дал более подробную информацию, но, к сожалению, ваш запрос не говорит, какое поле принадлежит какой таблице.Пожалуйста, предоставьте полную подробную информацию о схеме и индексах каждой таблицы для получения более подробной информации.

Кроме того, было бы неплохо узнать немного больше о поведении данных:несколько больших групп или много маленьких?Является ли item_name / itemcode уникальным ключом в одной таблице?и т. д. и т. д.

РЕДАКТИРОВАТЬ

Спасибо за добавление таблиц в поля в вашем запросе.Это все еще довольно ограниченно, не зная больше о данных, но я постараюсь вам помочь.

1). Вы не используете Item_Master в своих SELECT или GROUP BY

Это означает, что вы 'либо использовать его как фильтр (1: 0..1), либо как множитель (1: 1..many), либо как (1: 0..many).

Я полагаю, выиспользуйте его как фильтр.

2). Вы используете BETWEEN для фильтрации Inv_Date

Я предполагаю, что Inv_Date это DATETIME и не имеетчасть времени;это всегда полночь - представлять только даты.Предоставление 366 дат в вашем случае (високосный год) .

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

Есть 6 возможностей ...

1). Transport_Mode => Item_Name      => Inv_Date  
2). Transport_Mode => Inv_Date       => Item_Name  
3). Item_Name      => Transport_Mode => Inv_Date  
4). Item_Name      => Inv_Date       => Transport_Mode  
5). Inv_Date       => Transport_Mode => Item_Name  
6). Inv_Date       => Item_Name      => Transport_Mode  

Если у вас естьTransport_Mode Во-первых, он очень дружелюбен к вашему GROUP BY.Каждый возможный режим будет предварительно сгруппирован и готов к агрегации без сортировки.Затем для каждой группы вам просто нужно отфильтровать записи: JOIN для фильтрации Item_Name и BETWEEN для фильтрации Inv_Date.

Итак, индекс покрытия для (Transport_Mode, Item_Name, Inv_Date) кажетсяхорошо для меня.

Но это отчасти потому, что у вас есть 366 значений Inv_Date, которые покрывает ваш запрос.Если бы вас интересовал только один день, было бы лучше иметь (Inv_Date, Transport_Mode, Item_Name)

Но если у вас очень мало значений в Transport_Mode и много-много значений в Item_Name, возможно, вы бы выиграли отимея в своем индексе значение Item_Name до Transport_Mode?

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

Или создать его по одному и профилировать запрос, так как он использует разные индексы и планы выполнения.После этого вы можете оставить те, которые наиболее полезны для вас по всем вашим запросам, а не только один.

НО , во всех случаях убедитесь, что вы также индексировали itemcode на таблице Item_Master!

1 голос
/ 30 марта 2012

Это зависит от многих факторов.Вы можете попытаться принудительно использовать ваш индекс с подсказками запросов и сравнить планы выполнения (особенно примерное количество строк и стоимость для поиска по первичному ключу).Что такое избирательность к условию даты?В целом для этого запроса (на самом деле это зависит от структуры данных, но только в качестве предположения) индекс на (item_name, Transport_Mode) будет работать лучше.

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