Определение индексов: какие столбцы и влияние на производительность? - PullRequest
3 голосов
/ 23 декабря 2009

Я знаю, как использовать индексы (привязанные и не привязанные) Но когда я должен использовать не заблокированные индексы в моей таблице. Какие сценарии должны быть там, чтобы мой столбец не был привязан к индексу. Я прошел руководящие принципы MSDN, но все еще немного путаницы.

Должен ли я сделать только уникальные столбцы как NC или какие-либо другие столбцы также как NC.

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

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

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

Ответы [ 6 ]

8 голосов
/ 23 декабря 2009

Кластерный индекс определяет физическую структуру вашей таблицы (в определенной степени) - например, он определяет, в каком порядке упорядочены данные. Подумайте о телефонной книге, которая «сгруппирована» (LastName, FirstName) - по крайней мере, в большинстве стран это так.

Вы получаете только один кластеризованный индекс на таблицу - выбирайте его с умом! Согласно Евангелию Королевы индексирования, Кимберли Трипп , ключ кластеризации должен быть узким, стабильным (никогда не изменяться), уникальным (да!) И в идеале постоянно увеличивающимся.

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

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

Он должен быть уникальным, поскольку, опять же, это значение, используемое для поиска фактических данных. Если вы выберете столбец, который не гарантированно будет уникальным, SQL Server будет «унифицировать» ваш ключ кластеризации, добавив в него 4-байтовое значение - не очень хорошая вещь.

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

Идеальным кандидатом для ключа кластеризации может быть INT (или BIGINT) IDENTITY - он идеально соответствует всем этим требованиям.

Что касается некластеризованных индексов - используйте и выбирайте их с умом! Есть только одно общее правило, которое я могу вам дать: все столбцы, являющиеся частью внешнего ключа (ссылающиеся на другую таблицу), должны быть в индексе - SQL Server не будет (вопреки распространенному мнению и множеству мифов) размещать такой индекс на месте автоматически - никогда не имеет, никогда не делает.

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

4 голосов
/ 23 декабря 2009

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

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

Стоит ли использовать составной некластерный индекс (ы) для столбцов, которые являются внешними ключами?

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

2 голосов
/ 23 декабря 2009

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

Другое широкое правило (от Ричарда Кэмпбелла, на радио RunAs и DotNetRocks) заключается в том, что несколько широких индексов будут работать лучше, чем большее количество узких индексов. Широкий индекс будет охватывать более широкий диапазон запросов, и оптимизатор запросов будет меньше исследовать. Помните, что оптимизатор запросов имеет ограниченное время для запуска.

Исследовать SQL Server Profiler. Там есть инструменты (раньше они были автономными, но они изменились, и я недавно ими не пользовался). Они могут анализировать рабочие нагрузки и давать рекомендации по индексированию. Это будет лучший выбор, чем индексы, выбранные «интуитивно».

0 голосов
/ 23 декабря 2009

Если вы должны или не создавать кластерные индексы, зависит от вашей рабочей нагрузки (обычно преобладают количество и тип операторов SELECT, попадающих в вашу таблицу)

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

Пример: предположим, что вы храните CustomerOrders и часто хотите знать количество CustomerOrders (независимо от клиента) за определенный период времени. В этом случае может быть полезно создать кластерный индекс с OrderDate в качестве первого столбца. Если, с другой стороны, вы часто ищете все CustomerOrders с одним и тем же CustomerId, имеет смысл поместить CustomerId в качестве первого столбца в вашем кластерном индексе.

Недостаток кластеризованных индексов заключается не в самом кластеризованном индексе, а во вторичных индексах: вторичные индексы сами не кластеризованы (по определению, поскольку строки могут быть сохранены только один раз и хранятся в порядке кластеризованного индекса). ), а их индексные записи указывают на индексные записи кластерного индекса. Таким образом, для извлечения строки через вторичный индекс требуется 2 операции чтения: одна из вторичного индекса, а затем одна из кластеризованного индекса, на которую он указывает.

0 голосов
/ 23 декабря 2009

По каким полям вы ищете? Поиск? И т.п. Определите, какие поля вы используете при выполнении запросов (предложение WHERE) и они могли бы быть хорошими кандидатами.

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

Кроме того, мне помогло то, что Барт Дункан опубликовал давным-давно. Он заслуживает похвалы за это.

Статья была озаглавлена ​​«Используете ли вы отсутствующий индекс SQL DMV?». Найдите его и выполните этот запрос:

SELECT 

  migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure, 

  'CREATE INDEX [missing_index_' + CONVERT (varchar, mig.index_group_handle) + '_' + CONVERT (varchar, mid.index_handle) 

  + '_' + LEFT (PARSENAME(mid.statement, 1), 32) + ']'

  + ' ON ' + mid.statement 

  + ' (' + ISNULL (mid.equality_columns,'') 

    + CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN ',' ELSE '' END 

    + ISNULL (mid.inequality_columns, '')

  + ')' 

  + ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement, 

  migs.*, mid.database_id, mid.[object_id]

FROM sys.dm_db_missing_index_groups mig

INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle

INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle

WHERE migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) > 10

ORDER BY migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC

Это не лучшее решение для вас, но оно поможет вам определить некоторые показатели. И ссылка на статью: http://blogs.msdn.com/bartd/archive/2007/07/19/are-you-using-sql-s-missing-index-dmvs.aspx. По умолчанию, когда вы создаете PK в SQL Server, он по умолчанию является кластерным индексом, это не обязательно, но обычно это так.

0 голосов
/ 23 декабря 2009

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

Если вы часто выполняете эти запросы, вам следует создавать некластеризованные индексы, которые «покрывают» запрос, включая все столбцы, на которые имеются ссылки в индексе. Это должно включать любые неуникальные столбцы.

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

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