Удаление первичного ключа (кластеризованного индекса) для повышения производительности вставки

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

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

Запуск select top 10 возвращает недавно вставленные записи, а не «первые» записи. order by работает, конечно, но я ожидаю, что select top должен возвращать строки в зависимости от их порядка на диске, что, как я ожидаю, вернет самые низкие значения PK.

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

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

изменить

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

После расследования низкая производительность была связана не с операторами insert, а с функцией CLR, которая организовала аудит. После удаления CLR и использования прямой процедуры TSQL производительность повысилась в 20 раз.

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

// updating 10k rows in a table with trigger

// using CLR function
PK (identity, clustered)- ~78000ms
No PK, no index - ~81000ms

// using straight TSQL
PK (identity, clustered) - 2174ms
No PK, no index - 2102ms

person Kirk Broadhurst    schedule 31.08.2011    source источник


Ответы (4)


По словам Кимберли Трипп (Kimberly Tripp), королевы индексирования, наличие кластеризованного индекса в таблице действительно повышает производительность INSERT:

Продолжение споров о кластеризованных индексах

  • Вставка выполняется быстрее в кластеризованной таблице (но только в "правильной" кластеризованной таблице), чем в куче. Основная проблема здесь заключается в том, что поиск в IAM/PFS для определения места вставки в куче выполняется медленнее, чем в кластеризованной таблице (где место вставки известно и определяется кластеризованным ключом). Вставки выполняются быстрее при вставке в таблицу, где порядок определен (CL) и где этот порядок постоянно увеличивается.

Источник: сообщение в блоге под названием Дебаты о кластеризованном индексе продолжаются... .

person marc_s    schedule 01.09.2011
comment
Я обнаружил, что это верно, особенно когда размер таблицы увеличился. - person Kirk Broadhurst; 01.09.2011

Отличный тестовый сценарий и описание этого сценария доступны в блоге Тибора Караси по адресу SQLblog.com

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

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

И наоборот, пакетная вставка (10000 строк) выполняется быстрее в неиндексированный, а не в кластеризованный индекс (любой от 75% до 85% времени кластеризованной вставки).

clustered - loop        - 1689
heap      - loop        - 1713
clustered - one statement - 85
heap      - one statement - 62

Он описывает, что происходит на каждой вставке:

Куча: SQL Server должен найти, куда должна идти строка. Для этого он использует одну или несколько страниц IAM для кучи и связывает их с одной или несколькими страницами PFS для файлов базы данных. ИМО, здесь должен быть потенциал для заметных накладных расходов. И даже больше, когда многие пользователи забивают одну и ту же таблицу, я могу представить блокировку (ожидание) для страниц PFS и, возможно, также страниц IAM.

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

person Kirk Broadhurst    schedule 01.09.2011

Таблица без ключа? Нет даже автоинкрементного суррогатного ключа? :(

Пока ключ монотонно увеличивается, поддержка индекса при вставке должна быть хорошей — он просто "добавляется в конце". «Кластеризованный» просто означает, что физический макет таблицы соответствует индексу (поскольку данные являются частью индекса). Пока индекс не фрагментирован (см. бит монотонно увеличивающийся), сам кластер/данные не будут логически фрагментированы, и это не должно быть проблемой производительности. (Если есть обновления, то кластеризация — это немного другая история: обновленная запись может «разрастаться» и вызывать фрагментацию.)

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

Удачного кодирования.


Кроме того, любая зависимость от порядка, за исключением того, что исходит от ORDER BY, ошибочна по замыслу. Это может работать сейчас, но это деталь реализации, которая может незначительно измениться (например, другой план запроса). С ключом автоинкремента ORDER BY DESC всегда будет давать правильный результат (имейте в виду, что автоинкрементные идентификаторы можно пропустить, но если не «сбросить», они всегда будут увеличиваться в зависимости от порядка вставки).

person Community    schedule 01.09.2011
comment
Ваше здоровье. Я не полагаюсь на порядок, я просто использую его в менеджере, чтобы продемонстрировать, что индекс не обеспечивает согласованное размещение строк на диске. - person Kirk Broadhurst; 01.09.2011

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

Некоторые интересные тесты/сценарии, которые могут пролить свет на ваши конкретные обстоятельства: http://technet.microsoft.com/en-us/library/cc917672.aspx.

person Chains    schedule 01.09.2011