SQL Server: кластеризация по отметке времени; за и против - PullRequest
4 голосов
/ 21 апреля 2010

У меня есть таблица в SQL Server, где я хочу, чтобы вставки добавлялись в конец таблицы (в отличие от ключа кластеризации, который заставлял бы их вставлять в середину). Это означает, что я хочу, чтобы таблица была сгруппирована по некоторому столбцу, который будет постоянно увеличиваться.

Этого можно достичь путем кластеризации по столбцу datetime:

CREATE TABLE Things (
    ...
    CreatedDate datetime DEFAULT getdate(),
    [timestamp] timestamp,        

    CONSTRAINT [IX_Things] UNIQUE CLUSTERED (CreatedDate)
)

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

Я мог бы добавить фиктивный идентификатор int столбец и кластер на нем:

CREATE TABLE Things (
    ...
    RowID int IDENTITY(1,1),
    [timestamp] timestamp,        

    CONSTRAINT [IX_Things] UNIQUE CLUSTERED (RowID)
)

Но вы заметите, что моя таблица уже содержит столбец timestamp; столбец, который гарантированно будет монотонно увеличивающимся. Это именно та характеристика, которую я хочу для кандидатного ключа кластера.

Поэтому я кластеризовал таблицу по столбцу rowversion (он же timestamp):

CREATE TABLE Things (
    ...
    [timestamp] timestamp,        

    CONSTRAINT [IX_Things] UNIQUE CLUSTERED (timestamp)
)

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

То, что я ищу, это мысли о том, почему это плохая идея; и какие другие идеи лучше.

Примечание: Сообщество вики, так как ответы субъективны.

Ответы [ 4 ]

9 голосов
/ 21 апреля 2010

Итак, я разбил таблицу на столбец rowversion (он же отметка времени): Вместо добавления фиктивной личности столбец int (RowID) для обеспечения заказа, Я использую то, что у меня уже есть.

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

Основные требования к кластерному ключу (более подробную информацию см. В сообщении Кима Триппа ):

  • стабильный
  • узкая
  • уникальный
  • постоянно увеличивается, если это возможно

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

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

2 голосов
/ 21 апреля 2010

по ссылке: timestamp в вопросе:

Синтаксис метки времени устарел. Эта функция будет удалена в будущая версия Microsoft SQL Сервер. Избегайте использования этой функции в новые разработки и планируют изменить приложения, которые в настоящее время используют эта функция.

и

Повторяющиеся значения rowversion могут быть генерируется с помощью SELECT INTO заявление, в котором столбец rowversion находится в списке SELECT. Мы не рекомендую использовать rowversion в этом образом.

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

1 голос
/ 21 апреля 2010

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

CREATE TABLE Things (
    ...
    CreatedDate datetime DEFAULT getdate(),
    [timestamp] timestamp,        
)

CREATE CLUSTERED INDEX [IX_CreatedDate] ON .[Things] 
(
    [CreatedDate] ASC
)
0 голосов
/ 21 апреля 2010

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

...