Ограничение строки в составном первичном ключе в SQL Server 2014 - PullRequest
0 голосов
/ 21 декабря 2018

Я собираюсь вставить 2,3 миллиарда строк (2 300 000 000) из table_a в table_b.Схемы table_a и table_b идентичны, единственное отличие состоит в том, что table_a не имеет первичного ключа, но table_b настроил составной первичный ключ из 4 столбцов с 0 строками данных.Через 24 часа появляется сообщение об ошибке:

Сообщение 666, уровень 16, состояние 2, строка 1
Превышено максимальное уникальное значение, сгенерированное системой, для дублированной группы для индекса с идентификатором раздела422223771074560. Удаление и повторное создание индекса может решить эту проблему;в противном случае используйте другой ключ кластеризации.

Это мой составной PK в table_b и пример кода запроса, любая помощь будет благодарна.

column1: varchar(10), not null
column2: nvarchar(50), not null
column3: nvarchar(100), not null
column4: int, not null

Пример кода

insert into table_b
    select * 
    from table_a
    where date < '2017-01-01' -- some filters here

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

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

При создании ограничения PRIMARY KEY, уникальногоИндекс столбца или столбцов создается автоматически.По умолчанию этот индекс кластеризован;однако вы можете указать некластеризованный индекс при создании ограничения.

Когда уникальный индекс не для таблицы, каждая строка получает то, что документы называют "uniqueifier""длиной 4 байта (или ~ 2,14 миллиарда комбинаций)

Если кластерный индекс не создается со свойством UNIQUE, компонент Database Engine автоматически добавляет 4-байтовый столбец уникализатора в таблицу.Когда это требуется, компонент Database Engine автоматически добавляет значение уникализатора в строку, чтобы сделать каждый ключ уникальным.Этот столбец и его значения используются внутренне и не могут быть просмотрены или доступны пользователям.

Из этой информации и вашего сообщения об ошибке мы можем сказать две вещи:

  1. Существуеткластеризованный индекс в таблице
  2. В таблице нет первичного ключа

Учитывая объем данных, с которыми вы имеете дело, держу пари, у вас есть Clustered Columnstore Index для таблицы, которая в SQL Server 2014 не может включать первичный ключ.

Одним из возможных решений является разбиение table_b на основе определенного значения столбца (которое имеет менее 15K уникальных значений на основании ограничений, указанных в документации ).Напомним, что одно и то же усилие по разделению может оказать значительное влияние на минимизацию времени выполнения любых запросов с использованием table_b в зависимости от того, какой столбец используется в функции разделения.

0 голосов
/ 21 декабря 2018

Вы знаете, что:

Если кластеризованный индекс не создается с помощью свойства UNIQUE, компонент Database Engine автоматически добавляет 4-байтовый столбец уникализатора в таблицу.Когда это требуется, компонент Database Engine автоматически добавляет значение уникализатора в строку, чтобы сделать каждый ключ уникальным.Этот столбец и его значения используются внутри компании и не могут быть просмотрены или доступны пользователям.

Хотя маловероятно, что вы столкнетесь с проблемой, связанной с уникализаторами, мы видели редкие случаи, когда клиент достигаетпредел уникализатора 2 147 483 648, генерирующий ошибку 666.

И из этой темы о проблеме, которую мы имеем:

По состоянию на февраль 2018 г. цель разработки длямеханизм хранения не должен сбрасывать уникализаторы во время REBUILD.Таким образом, перестройка индекса в идеале не должна сбрасывать юниксификаторы, и проблема будет продолжать возникать при вставке новых данных со значением ключа, для которого унификаторы были исчерпаны.Но текущее поведение механизма отличается для одного конкретного случая, если вы используете оператор ALTER INDEX ALL ON REBUILD WITH (ONLINE = ON), он сбросит уникализаторы (для всех версий, начиная с SQL Server 2005 до SQL Server 2017).

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

...