Если в базе данных только одна вставка, плохо ли индексировать каждую возможную комбинацию столбцов?

23

Я работаю над системой отчетности, которая потребует больших запросов на выборку, но основана на базе данных, которая заполняется только один раз. Система управления базами данных - Microsoft SQL Server 2017. Вероятно, есть лучший способ создать такую ​​систему, но давайте подойдем к этому теоретически.

Теоретически говоря:

  1. Если у нас очень большая база данных (150M + строк в нескольких таблицах)
  2. И мы можем предположить, что база данных будет заполнена только один раз.

Может ли индексация каждой возможной комбинации столбцов оказать негативное влияние на производительность запроса select?

кривобокий
источник
4
Любая возможная комбинация непрактична в большинстве случаев. Более разумный подход - индексировать вручную, но очень щедро. Это определенно может иметь смысл.
usr
12
Я предлагаю переписать либо ваш заголовок, либо текст, выделенный жирным шрифтом, чтобы они соответствовали друг другу. С
первого
150M строк велика для одной таблицы, но невелика для базы данных. Практически говоря, системы отчетности используют только небольшое подмножество возможных комбинаций столбцов, лучше всего сосредоточиться на комбинациях клавиш, по крайней мере, на начальном этапе, а затем усложнять только при необходимости.
pojo-guy

Ответы:

36

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

Поскольку вы работаете на SQL Server 2017, загружаете один раз и запускаете отчеты, почему бы просто не использовать вместо этого кластерный индекс хранилища столбцов?

Это, кажется, идеальное решение для вашей потребности индексировать каждую возможную комбинацию столбцов.

Индексы Columnstore - Обзор

Эрик Дарлинг
источник
Columnstore - это то, к чему я бы тоже обращался, но мне просто интересно ... не работает ли оптимизатор прямо противоположно тому, что вы описали? Я имею в виду, что вместо сканирования доступных индексов и «размышлений» о том, какие из них могут быть полезны, разве он не анализирует запрос и не «думает о» идеальном индексе для этого запроса, а затем проверяет, существует ли он? (Если этого не произойдет, генерируется пропущенное индексное сообщение.) Если я прав (не знаю, просто догадываюсь), то даже если есть тысячи индексов, это не должно быть заметно дольше, чем при наличии нескольких их.
Лимонка
26

Если у вас есть N столбцов в таблице, каждая возможная комбинация столбцов равна 2 ^ N-1 (удаляя пустой набор). Для 10 столбцов это будет означать 1023 индекса, для 20 столбцов мы получим колоссальные 1048575 индексов. Большинство индексов никогда не будут использоваться, но должны быть приняты во внимание оптимизатором. Вполне возможно, что оптимизатор выберет неоптимальный индекс вместо лучшего. Я бы не стал идти по пути генерации всех видов индексов вместо того, чтобы пытаться выяснить, какие индексы действительно будут полезны.

РЕДАКТИРОВАТЬ исправлено количество возможных индексов

Как указывает Джефф , это даже хуже, чем 2 ^ N (установленная мощность), поскольку (3,2,1) явно отличается от (1,2,3). Для N столбцов мы можем выбрать первую позицию в индексе, который содержит все столбцы N способами. За вторую позицию по N-1 путям и т. Д. Поэтому мы в итоге получаем N! разные индексы в натуральную величину. Ни один из этих индексов не включен в другой индекс в этом наборе. Кроме того, мы не можем добавить еще один более короткий индекс, чтобы он не охватывался каким-либо полным индексом. Число индексов, следовательно, N !. Таким образом, пример для 10 столбцов становится 10! = 3628800 индексов и для 20 (барабанная дробь) 2432902008176640000 индексов. Это довольно большое число, если мы поставим точку для каждого индекса на один мм детали, световой луч пройдет 94 дня, чтобы пройти все точки. Все и все, не так ;-)

Леннарт
источник
6
Еще хуже: порядок столбцов в индексе может быть важен. Поэтому вы получите максимум N! индексов.
Джефф
2
Но вам не нужны индексы, которые являются префиксами других индексов.
Бармар
3
Это еще хуже. Для каждого индекса есть комбинации ASC и DESC.
ypercubeᵀᴹ
2
И что еще хуже, есть индексы ВКЛЮЧИТЬ.
ypercubeᵀᴹ
2
И огромное количество частичных индексов.
ypercubeᵀᴹ
7

Нет.

Индексировать «все» непрактично, но вы можете индексировать «большинство».

Вот вещь Если в таблице есть Nстолбцы, то число возможных индексов равно N!. Допустим, в таблице 10 столбцов, тогда у вас есть не только 10возможные индексы, но и 10!. То есть ... 3,628,800 ... на одном столе. Это много дискового пространства, дискового ввода-вывода, кеша и времени поиска.

Зачем? Несколько причин:

  • Индексы Lightwwight обычно кэшируются, что делает их быстрыми. Если у вас есть 3 миллиона из них, они НЕ будут кэшироваться.

  • Оптимизатор SQL может занять много времени, чтобы решить, какой из них лучше использовать, особенно при использовании объединений.

  • Оптимизатор SQL может отказаться от использования комплексного алгоритма и вместо этого попробовать эвристический алгоритм. Это может быть «менее чем оптимально». Например, в PostgreSQL есть разные опции для «менее 8-ми табличных запросов» и «более 8-ми табличных запросов».

  • Индексы должны быть легче, чем куча. Если вы все индексируете, тогда индекс становится таким же тяжелым, как куча ... что-то, что противоречит цели индекса.

Импалер
источник
Разве не номер 2 ^ 10? Каждый столбец либо включен, либо исключен из заданного индекса. Имеет ли значение заказ?
RemcoGerlich
2
@RemcoGerlich да, порядок имеет значение.
ypercubeᵀᴹ
2

Нет, это, вероятно, не окажет негативного влияния на SELECTзапросы, но

  • Это приведет к высокой загрузке диска.
  • Это значительно увеличит INSERTзатраты.
  • Большинство ваших индексов никогда не будут использованы.
  • Многие WHEREвыражения условий по-прежнему не будут использовать индексы, в основном более сложные.
  • Количество необходимых индексов будет увеличиваться экспоненциально с количеством столбцов. Т.е. если у вас есть, например, 8 столбцов, вам нужно 256 индексов для всех возможных комбинаций.
Петер говорит восстановить Монику
источник
Это может полностью вызвать проблемы во время компиляции.
Эрик Дарлинг
@sp_BlitzErik Как вы думаете, ORM в приложении?
Петер говорит восстановить Монику
Нет, смотри мой ответ.
Эрик Дарлинг
@sp_BlitzErik Wow, приятно видеть!
Петер говорит восстановить Монику