Удаление из SQL Server ColumnStore дает ошибку «Невозможно вставить дубликат ключа».

Наш продукт загружает данные из файлов CSV в различные таблицы через класс .NET System.Data.SqlClient.SqlBulkCopy. После успешной загрузки все данные старше определенной метки времени удаляются из базы данных. Это делается путем выполнения следующей команды до тех пор, пока строки не будут удалены:

DELETE TOP (100000) FROM DBO.TBL_DDBB WHERE MeasureDateTime < CAST('2020/04/05 00:00:00' as datetime)

Это прекрасно работает с таблицами в формате RowStore, но при выполнении этой команды на таблице с индексом ColumnStore мы получаем следующую ошибку:

Не удается вставить повторяющуюся ключевую строку в объект «dbo.deleted_bitmap» с уникальным индексом «tuple_key». Повторяющееся значение ключа (98, 0). Оператор был завершен.

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

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


Информация о версии используемого SQL Server:

Microsoft SQL Server 2016 (SP2-CU12) (KB4536648) — 13.0.5698.0 (X64)
15 февраля 2020 г. 01:47:30 Авторское право (c) Microsoft Corporation Standard Edition (64-разрядная версия) на Windows Server 2012 R2 Standard 6.3 (Сборка 9600:) (Гипервизор)


person Ide    schedule 11.06.2020    source источник
comment
У вас есть триггеры на таблицы, записывающие информацию из удаленных строк?   -  person AlwaysLearning    schedule 11.06.2020
comment
Неа; никаких триггеров, никаких ограничений, даже вторичных индексов. Я думаю, что объект dbo.deleted_bitmap, о котором упоминается в ошибке, является конструкцией SQL Server для обработки удаления строк в ColumnStores. Это точно не из наших.   -  person Ide    schedule 11.06.2020
comment
Посмотрите, закрыты ли группы строк, содержащие удаляемые данные. Поскольку удаление работает на других серверах, может быть разница между открытыми и закрытыми.   -  person Dan Guzman    schedule 11.06.2020
comment
Привет Дэн. Хорошее предложение, но я проверил, и, к сожалению, это не так.   -  person Ide    schedule 11.06.2020


Ответы (1)


columnstore : SQL Server помечает строку как логически удаленную, но не освобождает физическое хранилище для строки до тех пор, пока индекс не будет перестроен.

Логично предположить, что до тех пор, пока вы не перестроите данные индекса, они будут находиться в файле index.

После удаления вам необходимо перестроить индекс, чтобы восстановить ключ и пространство.

или ИЗМЕНИТЬ ИНДЕКС... РЕОРГАНИЗОВАТЬ

Дополнительные сведения о ссылка MSDN

как удалить работу в хранилище столбцов на хорошей странице bitmap/" rel="nofollow noreferrer">deleted_bitmap

person sandeep rawat    schedule 11.06.2020
comment
Это я знал, и, учитывая то, как работают ColumnStores, это имеет смысл. Но в ссылке не упоминается и не объясняется, почему возникает эта ошибка. Моя теория заключается в том, что SQL Server использует delete_bitmap для хранения уникальных идентификаторов удаленных строк, чтобы последующая команда ALTER INDEX.. REORGANIZE знала, что нужно удалить. Но если это так, то ошибка дублирования ключа должна означать, что строка удаляется дважды. И вот что меня озадачивает. - person Ide; 11.06.2020
comment
у вас есть топ 1000 каждый раз, когда вы будете получать одно и то же удаление .. просто сделайте переиндексацию, и вы не столкнетесь с этой проблемой или не удалите топ - person sandeep rawat; 11.06.2020
comment
здесь подробнее об удаленном_битмап aboutsqlserver.com/2014/05/06/ - person sandeep rawat; 11.06.2020
comment
@Я надеюсь на этот ответ. - person sandeep rawat; 11.06.2020
comment
у вас есть 1000 лучших каждый раз, когда вы будете получать одно и то же удаление. Если то, что вы говорите, верно, то это означает, что механизм удаления SQL Server не работает для ColumnStore. Когда вы удаляете строку, SQL Server должен действовать, если этой строки больше нет. Это касается любой операции, будь то вставка, выбор обновления или удаление. DELETE TOP 1000 удаляет 1000 строк, поэтому любой последующий оператор DELETE будет (или, скорее, должен) игнорировать ранее удаленные строки. Я не могу себе представить, что именно так Microsoft создала ColumnStores. - person Ide; 11.06.2020
comment
NB: как я уже говорил в своем первоначальном вопросе, механизм DELETE TOP 10000 работает на других серверах SQL. Проблема возникает (пока) только на этом конкретном сервере. - person Ide; 11.06.2020