Индексы SQL Server не помогают

У меня есть таблица (SQL 2000) с более чем 10 000 000 записей. Записи добавляются со скоростью примерно 80 000–100 000 в неделю. Раз в неделю из данных генерируются несколько отчетов. Отчеты обычно выполняются довольно медленно из-за небольшого количества индексов (предположительно, для ускорения операций INSERT). Один новый отчет мог бы действительно выиграть от дополнительного индекса в конкретном столбце "char(3)".

Я добавил индекс с помощью Enterprise Manager (Управление индексами -> Создать -> выбрать столбец, ОК) и даже перестроил индексы в таблице, но запрос SELECT совсем не ускорился. Любые идеи?

Обновление:

Определение таблицы:

ID, int, PK
Source, char(3)  <--- column I want indexed
...
About 20 different varchar fields
...
CreatedDate, datetime
Status, tinyint
ExternalID, uniqueidentifier

Мой тестовый запрос просто:

select top 10000 [field list] where Source = 'abc'

person Scott Isaacs    schedule 11.12.2008    source источник
comment
Для ответа на этот вопрос необходимы определение таблицы и строка запроса. Ошибка может быть совсем в другом.   -  person Tomalak    schedule 12.12.2008
comment
Также опубликуйте результаты EXPLAIN   -  person Eran Galperin    schedule 12.12.2008
comment
Сколько различных значений содержится в источнике по сравнению с количеством строк таблицы? Индекс КЛАСТЕРИРОВАН или нет?   -  person Tomalak    schedule 12.12.2008
comment
Другой индекс — это индекс CLUSTERED. В настоящее время существует около 400 вариантов Source, хотя некоторые из них используются гораздо чаще, чем другие.   -  person Scott Isaacs    schedule 12.12.2008
comment
По отношению к миллионам строк таблицы 400 различных значений не так уж много с точки зрения избирательности. Возможно, индекс даже не используется из-за этого. Попробуйте сделать Source индексом CLUSTERED.   -  person Tomalak    schedule 12.12.2008
comment
Насколько медленно мы говорим?   -  person Brody    schedule 12.12.2008
comment
Попробуйте сделать Source индексом CLUSTERED. Глоток. Возможно, вы захотите добавить еще одно поле в индекс для такой большой работы.   -  person dkretz    schedule 12.12.2008
comment
Мой пример запроса выше занимает 70 секунд, где запрос, где ID ›= [somevalue], занимает ~ 2 секунды. ID, PK, является CLUSTERED индексом. В производственной среде запросы немного сложнее, и их выполнение занимает несколько минут. Я уже знаю некоторые оптимизации запросов, которые я могу сделать там, как только получу это.   -  person Scott Isaacs    schedule 12.12.2008
comment
@doofledorfer: Какое значение имеет добавление другого поля, когда запрос просто фильтрует это одно поле?   -  person Tomalak    schedule 12.12.2008
comment
Я предполагаю, что есть потенциально другие запросы, которые выиграют от составного ключа. И пока вы все равно сортируете весь файл, это бесплатно. Делайте это максимально избирательно.   -  person dkretz    schedule 12.12.2008
comment
Составной ключ полезен, только если вы действительно запрашиваете компоненты вместе. Если такого случая не существует, составной ключ — это просто дополнительная работа в INSERT. Например, идентификатор должен жить как собственный индекс, потому что он, вероятно, будет запрашиваться сам по себе.   -  person Tomalak    schedule 12.12.2008
comment
Не было бы смысла создавать составной индекс, включающий уникальный столбец, забудьте о том, что он может быть запрошен отдельно. Но вы получаете только один кластеризованный индекс, поэтому сделайте его как можно более составным, если есть возможность использовать несколько столбцов. Этот 3-символьный источник является идеальным кандидатом.   -  person dkretz    schedule 12.12.2008
comment
Моя точка зрения такова: кластеризованный индекс по (a ASC, b ASC) не принесет вам много пользы, если вы фильтруете только по b, потому что b будет загроможден по всему индексу. Таким образом, добавление еще одного поля не имеет смысла, вы не собираетесь запрашивать все поля в индексе одновременно.   -  person Tomalak    schedule 12.12.2008
comment
@Tomalak, по сравнению с миллионами строк таблицы 400 различных значений - это немного с точки зрения избирательности, а? 0,25% так же избирательны для строк 1 MM, как и для строк 1K, это процент. Настоящий вопрос заключается в том, каков фактор кластеризации.   -  person    schedule 23.12.2008


Ответы (4)


Вам нужно посмотреть план запроса и посмотреть, использует ли он этот новый индекс - если это не так, есть пара вещей. Во-первых, у него может быть кэшированный план запроса, который он использует, и который не был признан недействительным с момента создания нового индекса. Если это не так, вы также можете попробовать подсказки индекса [ With (Index (yourindexname))].

10 000 000 строк не являются чем-то необычным, это должно быть прочитано довольно быстро.

person keithwarren7    schedule 11.12.2008
comment
он должен прочитать это довольно быстро, это смелое утверждение, учитывая тот факт, что вы ничего не знаете о конфигурации оборудования, версии SQL-сервера, объеме ОЗУ, другой нагрузке, настройке диска, ...) - person Tomalak; 12.12.2008
comment
Это была подсказка, которая мне была нужна (каламбур). Теперь запрос выполняется за ‹ 2 секунд. Спасибо. - person Scott Isaacs; 12.12.2008
comment
Томалак - хорошая мысль. Я просто сделал общее предположение, но, похоже, ему это удалось. - person keithwarren7; 12.12.2008
comment
Так что я думаю, что это показывает, что индекс не использовался автоматически из-за его низкой избирательности, и вместо этого произошло полное сканирование таблицы. - person Tomalak; 12.12.2008
comment
Мне было бы интересно посмотреть, запустит ли он после предоставления подсказки запрос без подсказки, изменил ли QP свой план сканирования этого индекса. Я сомневаюсь, что это проблема кардинальности с 10-миллионными записями, но он никогда не рассказывал нам о самой колонке и о том, что она представляла. - person keithwarren7; 12.12.2008
comment
Если я запускаю его с подсказкой, а затем снова без подсказки, он все равно будет медленным без него. - person Scott Isaacs; 12.12.2008

Используйте Показать план выполнения в анализаторе запросов SQL, чтобы увидеть, используется ли индекс.

Вы также можете попробовать сделать его кластеризованным индексом, если это еще не сделано.

person Jonas Elfström    schedule 11.12.2008

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

person Brad Barker    schedule 11.12.2008
comment
Ты хоть представляешь, какой эффект это может иметь? Как можно сказать наверное? Насколько вероятно? Сколько усилий они должны затратить? Как бы они взвесили, хорошая ли это идея? Звучит так, будто попробуй то, попробуй то. - person dkretz; 12.12.2008
comment
Это будет иметь эффект, но я не могу сказать вам, насколько сильно. Лучше использовать HashTable или выполнять последовательный поиск по списку при поиске элемента? Разделяй и властвуй произведения. Это КС1. - person Brad Barker; 12.12.2008
comment
CS1 не означает, что вам, вероятно, следует разбивать большие таблицы и индексы, потому что это может помочь. - person dkretz; 12.12.2008
comment
Будет больно при вставках, но вы говорите мне, что это не поможет при чтении? Серьезно? - person Brad Barker; 12.12.2008
comment
Я говорю, что это вопрос того, сколько боли и сколько помощи. Это не стоит всех накладных расходов на реализацию и поддержку ради прироста в 0,05%; что вполне возможно. Я говорю, что ваше предположение довольно случайное, если вы не уточняете и не сравниваете его, а просто говорите «вероятно», как если бы оно было очевидным. - person dkretz; 12.12.2008

 select top 10000 

Насколько уникальны ваши источники? Индексы полей с очень небольшим количеством значений обычно игнорируются механизмом SQL. Они делают запросы медленнее. Возможно, вы захотите удалить этот индекс и посмотреть, будет ли он работать быстрее, если ваше поле SOURCE содержит только несколько значений.

person jmucchiello    schedule 11.12.2008