Кластеризовать индекс по постоянно увеличивающемуся столбцу datetime в таблице журналов? - PullRequest
15 голосов
/ 07 февраля 2010

Я не администратор базы данных ( "Хорошо!", Вы будете думать через минуту. )

У меня есть таблица данных регистрации с этими характеристиками и схемами использования:

  • A datetime столбец для хранения временных меток журнала, значение которых постоянно увеличивается и в основном (но только в основном) уникально
  • Частые вставки (скажем, дюжина в минуту), только в конце диапазона меток времени (регистрируются новые данные)
  • Нечасто удаляется массово, начиная с начала диапазона отметок времени (старые данные очищаются)
  • Нет обновлений вообще
  • Частотный выбор выбирается с использованием столбца метки времени в качестве основного критерия наряду со вторичными критериями для других столбцов
  • Редкий выбор с использованием других столбцов в качестве критерия (и не , включая столбец отметки времени)
  • Хорошее количество данных, но недостаточно близко, чтобы я сильно беспокоился о месте хранения

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

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

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

Но я прочитал в этом ответе , который удаляет пропуски, которые не очищаются до тех пор, пока не будет перестроен индекс.

Все это подсказывает мне, что я должен:

  • Поместить кластеризованный индекс в столбец отметки времени со 100% -ным коэффициентом заполнения
  • Поместить некластеризованные индексы в любой другой столбец, который может использоваться в качестве критерия в запросе, который также не включает кластеризованный столбец (который может быть любым из них в моем случае)
  • Расписание массовых удалений, происходящих в течение ежедневного интервала обслуживания
  • Запланировать перестроение кластерного индекса сразу после массового удаления
  • Расслабьтесь и уходите больше

Я там с ума сошел? Нужно ли мне часто перестраивать этот индекс, чтобы избежать потери пространства? Есть ли другие очевидные (для администратора баз данных) вещи, которые я должен делать?

Заранее спасибо.

Ответы [ 4 ]

5 голосов
/ 08 февраля 2010

Вопреки тому, во что верят многие, наличие хорошего кластеризованного индекса в таблице может на самом деле сделать такие операции, как INSERT, быстрее - да, быстрее!

Ознакомьтесь с оригинальным сообщением в блоге Дебаты о кластеризованном индексе продолжаются .... Кимберли Трипп - окончательная королева индексации.

Она упоминает (примерно в середине статьи):

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

Важным моментом является то, что только с правильным кластеризованным индексом вы сможете воспользоваться преимуществами - когда кластерный индекс уникален, узок, стабилен и оптимально постоянно увеличивается. Лучше всего использовать столбец INT IDENTITY.

У Кимберли Трипп также есть отличная статья о том, как выбрать наилучший из возможных ключей кластеризации для ваших таблиц и каким критериям он должен соответствовать - см. Ее пост под названием Постоянно увеличивающийся ключ кластеризации - Дебаты по кластерным индексам ... ....... снова!

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

3 голосов
/ 07 февраля 2010

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

После массового удаления стоит перестроить индексы и обновить статистику. Это не только повышает производительность, но и сбрасывает индексы для указанного коэффициента заполнения.

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

3 голосов
/ 07 февраля 2010

Существует два «оптимальных» способа индексации таблицы регистрации большого трафика:

  1. столбец целочисленных идентификаторов в качестве первичного кластеризованного ключа
  2. уникальный идентификатор colum в качестве первичного ключа, с DEFAULT NEWSEQUENTIALID()

Оба метода позволяют SQL Server эффективно наращивать таблицу, поскольку он знает, что дерево индексов будет расти в определенном направлении.

Я бы не стал размещать какие-либо другие индексы в таблице или планировать перестройки индекса, если только не существует особой проблемы с производительностью.

0 голосов
/ 07 февраля 2010

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

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