Индексы базы данных: хорошо, плохо или пустая трата времени? - PullRequest
13 голосов
/ 24 ноября 2010

Добавление индексов часто предлагается здесь как средство от проблем с производительностью.

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

IЯ пробовал это средство много раз, на протяжении многих лет, как на DB2, так и на MSSQL, и результат всегда был разочаровывающим.

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

Я должен отметить, что мой опыт связан главным образом с небольшими таблицами (<100 000 строк). </p>

Может ли кто-нибудь дать некоторые практические рекомендации по выбору для индексации?

Правильный ответ: список рекомендаций, например:

  • Никогда / всегда индексировать таблицу с количеством записей NNNN меньше / больше
  • Никогда / всегда не учитывать индексы для несколькихключи поля
  • Никогда / всегда использовать кластерные индексы
  • Никогда / всегда использовать больше, чем индексы NNN в одной таблице
  • Никогда / всегда не добавлять индекс, когда [какое-то магическое условиеМне не терпится узнать о]

В идеале ответ даст несколько поучительных примеров.

Ответы [ 8 ]

18 голосов
/ 24 ноября 2010

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

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

Да, возможно, иногда.

12 голосов
/ 24 ноября 2010

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

Теперь, если у вас есть поля, которые вы часто используете в предложениях where, они могут получить выгоду от индексов, а также предоставляют несколько вещей:

  • Сначала поле должно иметь диапазон значений,Битовое поле или поле только с 2 или 3 значениями почти никогда не будет использовать индекс.

  • Во-вторых, запросы, которые вы пишете, должны обрабатываться.То есть они должны быть предназначены для использования индексов.Я подозреваю, что если вы никогда не добьетесь улучшения производительности от того, что выглядит как вероятные кандидаты в индексы, то у вас, вероятно, есть запросы, которые нельзя прорезать.Например, возьмите «WHERE Name вроде«% Smith »» в качестве предложения where.Не зная первых символов, оптимизатор не может использовать индекс.

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

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

5 голосов
/ 24 ноября 2010

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

Одна распространенная ошибка индекса, которую я вижу, это люди, задающиеся вопросом, почему выборка на col2 (или col3) занимает так много времени, когда индекс определяется как col1 ASC, col2 ASC, col3 ASC. Если у вас есть индекс с несколькими столбцами, в предложении WHERE должен использоваться первый столбец в индексе или первый и второй столбцы в индексе и т. Д.

Если вам нужен доступ к данным по col2, то вам нужен дополнительный индекс, который определяется как col2 ASC.

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

3 голосов
/ 24 ноября 2010

Вам нужны индексы. Только с индексами вы можете получить доступ к данным достаточно быстро.

Чтобы сделать его как можно короче:

  • добавить индексы для столбцов, по которым вы часто фильтруете (или группируете). (например, штат или название)
  • like и функции sql могут заставить СУБД не использовать индексы.
  • добавить индексы только для столбцов, которые имеют много разных значений (например, без логических полей)
  • Обычно добавляют индексы к внешним ключам, но это не всегда необходимо.
  • не добавлять индексы в очень короткие таблицы
  • никогда не добавляйте индексы, если вы не знаете, как они должны повысить производительность.

Наконец: посмотрите планы выполнения, чтобы решить, как оптимизировать запросы.

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

2 голосов
/ 24 ноября 2010

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

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

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

2 голосов
/ 24 ноября 2010
Always use clustered indexes.

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

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

1 голос
/ 24 ноября 2010

Если предполагается, что таблица является целью объединения, то лучше иметь кластеризованный индекс для этой таблицы, чтобы объединения могли выполняться последовательно через страницы данных.Столбцы в кластеризованном индексе (в некоторых системах БД) будут включены во все остальные индексы в этой таблице, поскольку это значения, которые индексы будут использовать для ссылки на данные таблицы.Чтобы другие индексы не становились слишком большими, столбцы в кластеризованном индексе должны быть как можно более узкими, поэтому лучше использовать только числовые, а не символьные типы данных в кластеризованном индексе.В целом, меньше столбцов лучше, чем больше столбцов, но обратите внимание, что три int столбца (12 байт на строку) намного лучше, чем один nvarchar(32) столбец (потенциально 64 байта на строку).

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

0 голосов
/ 24 ноября 2010

Кажется, вы путаете два понятия здесь. Добавление индексов * обычно может только сделать запрос на чтение быстрее, очень очень редко (почти никогда) медленнее. Добавление индекса никогда не заставляет оптимизатор запросов использовать его. Он будет использовать его только в том случае, если думает, что может извлечь из этого пользу, и, как правило, очень умно относится к этим решениям.

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

Это полностью отличается от , указывающего , что оптимизатор запросов ИСПОЛЬЗУЕТ индекс, фактически переопределяя то, что он будет делать сам по себе ... Это может потенциально замедлить запрос.

РЕДАКТИРОВАТЬ: отредактировано, чтобы исключить возможность неправильного толкования чрезмерно буквальными читателями.

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