Лучшие практики и анти-шаблоны при создании индексов в SQL Server? - PullRequest
16 голосов
/ 09 декабря 2008

Что вы должны учитывать при определении индексов, кластеризованных и некластеризованных, для SQL Server? Есть ли какие-либо анти-паттерны, о которых новички БД должны знать? Пожалуйста, объясните «почему» или предоставьте ссылки, если это возможно.

Ответы [ 8 ]

13 голосов
/ 09 декабря 2008

Индекс - это в основном "шпаргалка". Это позволяет СУБД находить определенное значение (или диапазон значений) на диске без необходимости сканирования всей таблицы. Как правило, вы платите небольшой штраф за INSERT / UPDATE / DELETE, имея индекс, но редко настолько, что это само по себе является узким местом. Хорошие СУБД будут использовать индексы только тогда, когда они помогают повысить производительность запросов, поэтому здесь не так уж много негативных анти-паттернов; Обычно это не очень больно, если у вас есть дополнительные индексы (если вы не говорите об очень транзакционных таблицах). Тем не менее, тщательная индексация по всем направлениям поможет вам убедиться, что действительно важные из них есть, и лучший способ выяснить это - профилировать ваше приложение.

Ключом к пониманию того, когда и когда не следует использовать индексы, является понимание того, что они действительно делают под прикрытием. Короче говоря, вы хотите их, когда селективность индекса высока (т. Е. Число различных возможных значений велико по сравнению с размером отношения). Так, например, если у вас есть таблица с 10000 строк, и у вас есть столбец с именем «color» для этой таблицы, который является «красным» или «синим», это не очень помогает иметь индекс, потому что СУБД вероятно, в любом случае придется загружать большинство страниц в память (при условии случайного распределения). И наоборот, индекс по первичному идентификатору ключа таблицы (который почти всегда добавляется автоматически) заставит поиск в этой таблице быстро светиться - порядка log (n) - потому что очень небольшое число узлов в дереве должно изучить страницу на диске, где находится запись.

Индексы в большинстве современных систем баз данных реализованы с помощью дерева B +, которое является очень классным вариантом B-Trees, оптимизированных для медленного вторичного хранения (диски вместо памяти). Вы можете получить хорошее представление об их использовании и функциональности в Системы баз данных: Полная книга .

4 голосов
/ 09 декабря 2008

Не тестируйте индексы и не оптимизируйте запросы без базы данных, заполненной репрезентативными данными.

База данных обычно игнорирует любой индекс в логическом поле. Он будет игнорировать его как часть составного индекса. (Однако см. «Фильтрованный индекс» в SQL Server 2008.)

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

Не думай ничего. Протестируйте все.

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

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

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

2 голосов
/ 09 декабря 2008

Вот еще пара индексирующих шаблонов, которые я видел или был виновен:

Общее покрытие - Размещение индексов на таблицах с небольшим или нулевым ростом и (очень) низким количеством строк. Это контрпродуктивно, так как поиск индекса может занять больше времени, чем сканирование таблицы.

Индекс промышленной прочности - Размещение индекса в столбце первичного ключа. Меня попросили сделать это, чтобы «ускорить» запрос.

2 голосов
/ 09 декабря 2008

Blunderbus - индексный анти-паттерн, в котором я был виновен в прошлом. Поместить индекс или варианты того же индекса в столбцы таблицы, не рассматривая план объяснения и не понимая, как работает оптимизатор.

1 голос
/ 20 января 2009

Размещение кластерного индекса в столбце GUID в большинстве случаев не очень хорошая идея. Кластерный индекс определяет физический порядок хранения данных. Поэтому лучше всего кластеризовать индекс в столбце, который увеличивается или уменьшается и является уникальным.
(Если кластеризованный индекс не является уникальным, SQL Server автоматически добавит PK в кластеризованный индекс). Guid - это случайное значение (если вы не уверены, что используете последовательные guid), так что это означает, что каждый раз, когда вы вставляете или обновляете guid в столбце, который является частью кластерного индекса, Sql Server будет вынужден перемещать записи в страницы данных.

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

1 голос
/ 09 декабря 2008

Одна вещь, которую я обнаружил, что люди забывают делать при индексации, это индексировать внешний ключ. Индексы первичных ключей создаются автоматически (я говорю на SQL Server, другие базы данных могут отличаться), а внешние ключи - нет. Но многие люди считают, что это так (предположительно, те же люди, которые предполагают, что триггеры будут действовать только на одну запись за раз). Поскольку они почти всегда участвуют в объединениях (зачем еще их иметь?), Большую часть времени их нужно индексировать (исключение будет очень маленькой таблицей).

Я бы определил мой любимый индексный анти-шаблон как: Почему мои запросы такие медленные - условие, которое возникает, когда люди, не работающие с базами данных, проектируют большие базы данных и даже не знают достаточно, чтобы поместить в них какие-либо индексы. Типичный симптом обнаруживается на доске объявлений, когда человек спрашивает, почему на простой запрос к 50-миллионной таблице записей уходит 40 минут. Вероятно, этот антипаттерн будет встречаться с множеством других шаблонов антивирусных баз данных, поскольку вряд ли кто-то, даже не знакомый с индексацией, разработал эффективную или действенную структуру базы данных.

1 голос
/ 09 декабря 2008

Я вижу, как люди просто пользуются помощником по настройке ядра СУБД и думают, что он достаточно умен, чтобы предлагать наиболее оптимальные индексы и статистику. Это шаблон, который вы должны избегать.

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

Подберите книгу о запросах T-SQL Ицик Бен-Гана (MS Press), когда вы в следующий раз будете в книжном магазине (у них будет). Прочтите первые 3 главы, и в них будет рассказано о том, как работает процесс запросов внутри SQL Server - поскольку ваша работа с этой конкретной технологией может оказаться самой важной из трех глав, которые вы когда-либо читали.

1 голос
/ 09 декабря 2008

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

...