Кластерный индекс должен содержать столбец (столбцы), к которым чаще всего запрашиваются, чтобы дать наибольшую вероятность поиска или создания некластеризованного индекса, охватывающего все столбцы в запросе.
Первичный ключ и кластеризованный индексне должно быть таким же.Они оба являются ключами-кандидатами, и таблицы часто имеют более одного такого ключа.
Вы сказали
Кроме того, я не вижу в этом никакой пользы, поскольку можно было бычасто запрашивать все эти поля для обоснования кластеризованного индекса, верно?
Это не так.Поиск можно выполнить, просто используя первый или два столбца кластерного индекса.Это может быть дальний поиск, но это все еще поиск.Вам не нужно указывать все его столбцы, чтобы получить эту выгоду.Но порядок столбцов имеет большое значение.Если вы в основном обращаетесь к клиенту, то столбец «Последовательность» является плохим выбором, поскольку он является первым в кластерном индексе.Выбор второго столбца должен быть элементом, который больше всего запрашивается в связи с первым (не сам по себе).Если вы обнаружите, что второй столбец запрашивается сам по себе почти так же часто, как и первый столбец, тогда поможет некластеризованный индекс.
Как уже говорили другие, сокращение числа столбцов / байтов в кластеризованном индексе на столько женасколько это возможно, важно.
Очень плохо, что последовательность является случайным значением, а не увеличивается, но это не поможет.Ответ не для добавления в столбец идентификаторов, если только ваше приложение не может начать использовать его в качестве основного условия запроса для этой таблицы (маловероятно).Теперь, поскольку вы застряли в этом столбце случайной последовательности (предположим, что он наиболее часто запрашиваемый), давайте посмотрим на другое из ваших утверждений:
наличие этих полей в качестве кластеризованного индекса будет очень вреднымвставить производительность, поскольку данные должны были бы физически переупорядочиваться при каждой вставке.
Это не совсем так.
Физическое расположение на диске не совсем то, что мыречь идет здесь, но это вступает в игру с точки зрения фрагментации, которая является показателем производительности.
Строки внутри каждой 8k-страницы не упорядочены.Просто все строки на каждой странице меньше, чем на следующей странице, и больше, чем на предыдущей.Проблема возникает, когда вы вставляете строку и страница заполнена: вы получаете разделение страницы.Движок должен скопировать все строки после вставленной строки на новую страницу, и это может быть дорого.Со случайным ключом вы получите много расколов страницы.Вы можете улучшить проблему, используя меньший коэффициент заполнения при перестройке индекса.Вам нужно поиграть с ним, чтобы получить правильный номер, но 70% или 60% могут служить вам лучше, чем 90%.
Я считаю, что использование даты и времени в качестве второго столбца CI может быть полезным, так как выВы по-прежнему будете иметь дело со страницами, которые нужно разделить между двумя различными значениями Sequence, но это не так плохо, как если бы второй столбец в CI также был случайным, так как вы гарантированно разбивали страницы при каждой вставке, где свозрастающее значение, вам может повезти, если строку можно добавить на страницу, потому что следующий порядковый номер начинается на следующей странице.
Сокращение типов данных и количества всех столбцов в таблице, а также ее некластеризованногоИндексы также могут повысить производительность, так как больше строк на страницу = меньше чтений страниц за запрос.Особенно, если двигатель вынужден делать сканирование таблицы.Перемещение группы редко запрашиваемых столбцов в отдельную таблицу 1-1 может творить чудеса с некоторыми вашими запросами.
Наконец, есть некоторые изменения в дизайне, которые также могут помочь (на мой взгляд):
- Измените столбец Sequence на bigint, чтобы сохранить байт для каждой строки (8 байтов вместо 9 для числового значения).
- Используйте справочную таблицу для Клиента с 4-байтовым столбцом идентификации int вместо varchar (9).Это экономит 5 байтов на строку.Если возможно, используйте smallint (от -32768 до 32767), который составляет 2 байта, что еще больше экономит 7 байтов на строку.
Сводка: CI должен начинаться с столбца, к которому чаще всего обращаются.Удалите все столбцы из CI, которые вы можете.Укоротите столбцы (байты) как можно больше.Используйте более низкий коэффициент заполнения, чтобы смягчить разрывы страниц, вызванные случайным столбцом «Последовательность» (если он должен оставаться первым из-за наибольшего количества запросов).
О, и начните выполнять дефрагментацию в Интернете.Если таблицу нельзя изменить, по крайней мере, ее можно часто реорганизовывать, чтобы поддерживать ее в наилучшей возможной форме.Также не пренебрегайте статистикой, поэтому движок может выбрать соответствующие планы выполнения.
UPDATE
Еще одна стратегия, которую следует рассмотреть, - это если составной ключ, используемый в таблице, можетбыть преобразован в int, и таблица поиска значений создается.Допустим, некоторая комбинация из менее чем 4 столбцов повторяется в более чем 100 строках, например, Sequence + Client + Hash, но только с различными значениями Date.Тогда вставка в отдельную таблицу SequenceClientHash со столбцом идентификаторов может иметь смысл, потому что тогда вы можете один раз найти искусственный ключ и использовать его снова и снова.Это также заставит ваш CI добавлять новые строки только на последней странице (yay) и существенно уменьшит размер CI, как повторяется для всех некластеризованных индексов (yippee).Но это имело бы смысл только в определенных узких шаблонах использования.
Теперь marc_s предложил просто добавить дополнительный столбец с идентификационными данными int в качестве кластеризованного индекса.Возможно, это могло бы помочь, если бы все некластеризованные индексы получали больше строк на страницу, но все зависит от того, где именно вы хотите, чтобы производительность была, потому что это гарантировало бы, что каждый запрос таблицы должен использовать закладку.поиск, и вы никогда не сможете получить поиск по таблице.
О «тоннах разбиения страниц и плохой фрагментации индекса»: как я уже говорил, это можно несколько улучшить при более низком коэффициенте заполнения.Кроме того, частая реорганизация индекса в сети (не то же самое, что перестройка) может помочь уменьшить эффект от этого.
В конечном счете, все сводится к точной системе и ее уникальной схеме доступа к данным в сочетании с решениями о том, какие частиВы хотите оптимизировать.Для некоторых систем медленная вставка неплоха, если выбор всегда быстрый.Для других более важно иметь постоянное, но немного более медленное время выбора, чем немного более быстрое, но непоследовательное время выбора.Для других данные в действительности не читаются до тех пор, пока они не будут переданы в хранилище данных, поэтому вставки должны быть максимально быстрыми.И в добавление к этому добавляется тот факт, что производительность зависит не только от времени ожидания пользователя или даже времени ответа на запрос, но и от ресурсов сервера, особенно в случае массового параллелизма, так что общая пропускная способность (скажем, в ответах клиента за единицу времени)имеет значение больше, чем любой другой фактор.