Почему BULK INSERT/BCP включает оператор Sort, хотя я сделал все, чтобы этого избежать? (SQL сервер 2012)

У меня проблема с процессом BULK INSERT/BCP, который включает оператор сортировки, хотя я сделал все, чтобы этого избежать. Во-первых, я экспортировал данные в файл с BCP (собственный формат), используя запрос и с предложением «ORDER BY Id ASC, Created ASC». Это дало мне файл с отсортированными данными. Во-вторых, я использовал следующий T-SQL для импорта данных:

BULK INSERT dbo.LSZ_Table
FROM
    'T:\LSZ\data_file_native.dat'
WITH
    (
        FORMATFILE='T:\LSZ\format_n.xml'
        ,KEEPNULLS
        ,KEEPIDENTITY
        ,TABLOCK 
        ,ORDER (Id ASC, Created ASC)
        ,ROWS_PER_BATCH = 57380362
    )

ROWS_PER_BATCH = 57380362 — я знаю это, потому что ранее экспортировал данные. Идентификатор столбца имеет тип int с определенным идентификатором, а не null. Столбец Created имеет тип datetime, а не null.

Отступление: некоторые могут спросить, почему такой порядок сортировки «Id ASC, Created ASC», это потому, что таблица, которая будет заполнена данными, является промежуточной таблицей, которая будет включена в качестве одного из разделов (ключ разделения Создан) и поскольку уникальные индексы в секционированных таблицах должны иметь столбец секционирования как часть ключа, в котором мой индекс «кластеризованный, уникальный, первичный ключ» имеет определение ключа (Id ASC, Created ASC).

Промежуточная таблица с индексом «кластеризованный, уникальный, первичный ключ» (Id ASC, Created ASC) пуста перед импортом, я хочу воспользоваться преимуществами минимального ведения журнала и одновременного импорта в кластеризованный индекс.

Файл формата содержит такую ​​информацию о ключевых столбцах:

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <RECORD>
  <FIELD ID="1" xsi:type="NativeFixed" LENGTH="4"/>
  ...
  <FIELD ID="31" xsi:type="NativeFixed" LENGTH="8"/>
  ...
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="Id" xsi:type="SQLINT"/>
  ...
  <COLUMN SOURCE="31" NAME="Created" xsi:type="SQLDATETIME"/>
  ...
 </ROW>
</BCPFORMAT>

Теперь, что мне не хватает в моей процедуре или что я здесь делаю неправильно, что заставляет SQL Server вставлять оператора сортировки в план выполнения ?? Я думаю, мне не нужно объяснять, почему я хочу, чтобы этот оператор Sort был исключен из плана :) Ссылка на план выполнения


Версии: Microsoft SQL Server 2012 — 11.0.5548.0 (X64) Developer Edition (64-разрядная версия) для Windows NT 6.1 (сборка 7601: пакет обновления 1)


person LSZ    schedule 12.06.2015    source источник


Ответы (1)


Итак, мне удалось решить проблему. На самом деле, скорее всего, я столкнулся с ошибкой в ​​продукте. Когда я попытался выполнить ту же BULK INSERT, но для таблицы без свойства Identity, неприятная сортировка исчезла. Я нашел трюк для загрузки таблицы без Identity, а затем использовать ALTER TABLE SWITCH для переключения (с изменением метаданных и без физических операций ввода-вывода, если все сделано аккуратно) в таблицу с свойством Identity. Это работает и для неразделенных таблиц (поскольку каждая таблица имеет по крайней мере один раздел). Я обнаружил элемент подключения, открытый в 2008 году, который сообщал об этой проблеме, и, к моему удивлению, он все еще активен, и проблема все еще присутствует в SQL Server 2012.

Если вы столкнулись с той же проблемой, проголосуйте за элемент подключения: https://connect.microsoft.com/SQLServer/feedback/details/348970/bulk-insert-with-identity-column-creates-query-план-с-сортировкой

person LSZ    schedule 20.06.2015