Сколько индексов базы данных слишком много?

98

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

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

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

Итак, сколько индексов считается слишком большим? 10? 25? 50? Или я должен просто накрыть действительно, действительно общие и очевидные случаи и игнорировать все остальное?

Теги:
database
database-design

17 ответов

75
Лучший ответ

Это зависит от операций, которые происходят в таблице.

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

Если таблица сильно пострадает от UPDATE, INSERT + DELETE... они будут очень медленными с большим количеством индексов, так как все они должны быть изменены каждый раз, когда происходит одна из этих операций.

Сказав это, вы можете явно добавить много бессмысленных индексов в таблицу, которая ничего не сделает. Добавление индексов B-Tree в столбец с двумя разными значениями будет бессмысленным, поскольку оно не добавляет ничего с точки зрения поиска данных. Чем уникальнее значения в столбце, тем больше он будет выигрывать от индекса.

  • 1
    Просто чтобы уточнить, индекс в 2 значениях может быть бессмысленным в конкретном случае, когда одно значение встречается редко, и вы хотите посмотреть его. Так что дело не в том, насколько уникальны значения, а в том, насколько избирателен индекс.
41

Я обычно так делаю.

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

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

24

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

alter index my_index_name monitoring usage;

Затем вы можете проверить, используется ли индекс с этой точки вперед, запросив v $object_usage. Информацию об этом можно найти в Руководство администратора базы данных Oracle.

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

12

В хранилище данных очень часто бывает большое количество индексов. Я работал с таблицами фактов, имеющими две сотни столбцов и 190 из них проиндексированы.

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

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

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

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

  • 0
    Что много на самом деле? Я бы догадался, что ты собираешься сказать размерность. Это довольно странный случай. Но, ты рок как администратор базы данных, так что я хочу сказать, я явно что-то упустил.
  • 0
    @Stephanie, у нас очень похожий сценарий. Дэвид упомянул, что это растровые индексы. Мы также используем индексы BITMAP JOIN. Да, по фактам. Oracle может выполнять очень эффективные операции AND над битовыми индексами. Например, у вас может быть предложение WHERE с 5 атрибутами низкой мощности, каждый из которых имеет индекс растрового изображения. Если вы посмотрите на план выполнения, он будет иметь операции с битовой картой AND (в основном это эффективная битовая карта и операция), а затем вниз по плану выполнения вы увидите преобразование битовой карты в rowids. Это действительно быстро.
11

В парафразе Einstein об простоте добавьте столько индексов, сколько вам нужно, и не более.

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

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

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

  • 1
    Я согласен на переоценку. Хорошее управление никогда не является задачей «поставь и забудь». Изменения в программном обеспечении. Требования меняются. Изменения в использовании. Новая, казалось бы, тривиальная функциональность, представленная в один прекрасный день, может быстро стать вашим самым большим узким местом, а вчерашний краеугольный программный код может стать неактивным и ненужным жиром, который просто зависает от потребления ресурсов. Я также согласен с итеративным подходом. Если вы сделаете слишком много сразу, вы не узнаете, что сработало.
5

Я сделал несколько простых тестов в своем реальном проекте и в реальной базе данных MySql. Я уже ответил в этой теме: Какова стоимость индексации нескольких столбцов db?

Но я думаю, что будет лучше, если я приведу его здесь:

Я сделал несколько простых тестов, используя мой реальный проект и реальную базу данных MySql.

Мои результаты: добавление среднего показателя (1-3 столбца в индексе) к таблице - делает вставки медленнее на 2,1%. Так что если вы добавляете 20 индексов, ваши вставки будут медленнее на 40-50%. Но ваши избранные будет в 10-100 раз быстрее.

Итак, можно добавить много индексов? - Это зависит:) Я дал тебе свои результаты - Ты решать!

5

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

Как всегда, все просто. Если есть искаженные столбцы и гистограммы, то это может быть плохой идеей.

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

  • 0
    Я проголосовал, но ... я бы сказал, что дополнительное время анализа, хотя и интересное и академичное, никогда не повлияет на мой выбор правильного числа индексов. согласна?
  • 0
    @StephaniePage Я не провел эксперимент, чтобы что-то доказать. Однако я видел проект, который наивно создавал индекс по одному столбцу для каждого столбца. Если некоторые таблицы имеют 80 столбцов, я думаю, это может начать оказывать влияние. Похоже, Oracle учитывает стоимость доступа по каждому индексу. Но да, я согласен, есть более важные вещи, чтобы рассмотреть, чем это.
Показать ещё 1 комментарий
3

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

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

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

2

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

Вы можете терпеть дополнительное время, необходимое для завершения обновления?

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

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

2

Нет никакого статического ответа, на мой взгляд, такого рода вещи подпадают под "настройку производительности".

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

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

Если вся ваша БД находится на фасаде хранимых процедур, то поворот становится немного проще, так как вам не нужно беспокоиться о каждом специальном запросе. Или у вас может быть глубокое понимание тех запросов, которые попадут в вашу БД, и могут ограничить их настройками.

Для SQL Server я нашел советника по настройке ядра базы данных полезным - вы настроили "типичные" рабочие нагрузки и можете давать рекомендации по добавлению/удалению индексов и статистики. Я уверен, что у других БД есть похожие инструменты: "официальные" или сторонние.

2

Это действительно более теоретические вопросы, чем практические. Влияние индексов на вашу производительность зависит от вашего оборудования, версии Oracle, типов индексов и т.д. Вчера я слышал, что Oracle анонсировала выделенное хранилище, сделанное HP, которое должно выполнять в 10 раз быстрее с базой данных 11g. Что касается вашего дела, может быть несколько решений: 1. Имейте большое количество индексов ( > 20) и перестраивайте их ежедневно (в ночное время). Это было бы особенно полезно, если таблица ежедневно получает тысячи обновлений/удалений. 2. Разделите свою таблицу (если это применит ваша модель данных). 3. Используйте отдельную таблицу для новых/обновленных данных и выполните ночной процесс, который объединяет данные вместе. Это потребует изменения в вашей логике приложения. 4. Перейдите в IOT (индексная организованная таблица), если ваши данные поддерживают это.

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

  • 0
    Я не понимаю, как может помочь перестройка индексов или как может помочь IOT.
  • 0
    IOT - если есть возможность перепроектировать приложение так, чтобы использовался новый определенный пользователем тип данных, то IOT сэкономил бы издержки при индексации таблицы. это может быть не так здесь. это действительно зависит. перестройка индекса - в случае, если индексов много, а новые данные не индексируются.
Показать ещё 2 комментария
2

Одна вещь, которую вы можете рассмотреть, - это создание индексов для таргетинга на стандартную комбинацию поиска. Если обычно используется столбец1, и с ним часто используется столбец2, а column3 иногда используется с столбцом2 и столбцом1, то индекс для столбца1, столбца2 и столбца3 в этом порядке может использоваться для любого из этих трех обстоятельств, хотя это только один индекс, который необходимо сохранить.

2

Если вы в основном читаете (и несколько обновлений), то нет причин не индексировать все, что вам нужно индексировать. Если вы часто обновляетесь, вам может потребоваться осторожность в отношении того, сколько индексов у вас есть. Там нет жесткого номера, но вы заметите, когда все начнет замедляться. Удостоверьтесь, что ваш кластеризованный индекс - тот, который имеет наибольший смысл на основе данных.

1

Сервер Sql дает вам хорошие инструменты, которые позволяют вам видеть, какие индексы используются на самом деле. Эта статья, http://www.mssqltips.com/tip.asp?tip=1239, дает вам несколько запросов, которые позволяют лучше понять, насколько используется индекс, в отличие от того, как многое обновляется.

1

На самом деле это не так: не добавляйте индекс, если не знаете (а это часто означает сбор статистики использования), что он будет использоваться гораздо чаще, чем он обновляется.

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

1

Сколько столбцов есть? Мне всегда говорили делать индексы с одним столбцом, а не с несколькими столбцами. Таким образом, не больше индексов, чем количество столбцов, IMHO.

0

Он полностью основан на столбцах, которые используются в разделе Where Where. И как "Правило большого пальца", у нас должны быть указатели на столбцы внешнего ключа, чтобы избежать DEADLOCKS. Отчет AWR должен анализировать периодически, чтобы понять необходимость индексов.

  • 2
    Индексы для столбцов внешнего ключа, чтобы избежать взаимоблокировок? У вас есть справка, которая объясняет, почему и как это происходит?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню