Создание Первичного ключа на временной таблице - Когда?

У меня есть хранимая процедура, которая работает с большим объемом данных. У меня есть те данные, вставляемые в к временной таблице. Полный поток событий - что-то как

CREATE #TempTable (
    Col1    NUMERIC(18,0) NOT NULL,    --This will not be an identity column.
    ,Col2   INT NOT NULL,
    ,Col3   BIGINT,

    ,Col4   VARCHAR(25) NOT NULL,
    --Etc...

    --
    --Create primary key here?
)


INSERT INTO #TempTable
SELECT ...
FROM MyTable
WHERE ...

INSERT INTO #TempTable
SELECT ...
FROM MyTable2
WHERE ...

--
-- ...or create primary key here?

Мой вопрос состоит в том, когда наилучшее время должно создать первичный ключ на моей таблице #TempTable? Я теоретизировал, что должен создать ограничение/индекс первичного ключа после того, как я вставляю все данные, потому что индекс должен быть реорганизован, поскольку информация о первичном ключе создается. Но я понял, что мое подчеркивание предположения могло бы быть неправильным...

В случае, если это релевантно, типы данных, которые я использовал, реальны. В #TempTable таблица, Col1 и Col4 будет составлять мой первичный ключ.

Обновление: В моем случае я делаю первичный дубликат ключа исходных таблиц. Я знаю, что поля, которые составят мой первичный ключ, всегда будут уникальны. У меня нет озабоченности по поводу неудавшегося, изменяют таблицу, если я добавляю первичный ключ в конце.

Хотя, это в стороне, мой вопрос все еще стоит как, который быстрее предполагает, что оба успешно выполнились бы?

24
задан ahsteele 20 September 2019 в 15:19
поделиться

7 ответов

Это во многом зависит.

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

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

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

Однако, как отмечали другие, создание индекса могло завершиться ошибкой. Кроме того, временная таблица не существует изолированно. По-видимому, существует лучший индекс для чтения данных из него для следующего шага. Этот индекс должен быть либо на месте, либо создан.

17
ответ дан 29 November 2019 в 00:04
поделиться

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

например:

-- first, create the table
SELECT ...
INTO #TempTable
FROM MyTable
WHERE ...
UNION ALL
SELECT ...
FROM MyTable2
WHERE ...

-- now, add a non-clustered primary key:
-- this will *not* recreate the table in the background
-- it will only create a separate index
-- the table will remain stored as a heap
ALTER TABLE #TempTable ADD PRIMARY KEY NONCLUSTERED (NonNullableKeyField)

-- alternatively:
-- this *will* recreate the table in the background
-- and reorder the rows according to the primary key
-- CLUSTERED key word is optional, primary keys are clustered by default
ALTER TABLE #TempTable ADD PRIMARY KEY CLUSTERED (NonNullableKeyField) 

В противном случае у Кейда Ру был хороший совет относительно: до или после.

6
ответ дан 29 November 2019 в 00:04
поделиться

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

3
ответ дан 29 November 2019 в 00:04
поделиться

Даже более важным, чем соображения производительности, если вы не АБСОЛЮТНО, на 100% уверены, что у вас будут уникальные значения, вставленные в таблицу, сначала создайте первичный ключ. В противном случае создать первичный ключ не удастся.

Это предотвращает вставку повторяющихся / неверных данных.

2
ответ дан 29 November 2019 в 00:04
поделиться

If you add the primary key when creating the table, the first insert will be free (no checks required.) The second insert just has to see if it's different from the first. The third insert has to check two rows, and so on. The checks will be index lookups, because there's a unique constraint in place.

If you add the primary key after all the inserts, every row has to be matched against every other row. So my guess is that adding a primary key early on is cheaper.

But maybe Sql Server has a really smart way of checking uniqueness. So if you want to be sure, measure it!

1
ответ дан 29 November 2019 в 00:04
поделиться

Я не думаю, что это имеет какое-либо существенное значение в вашем случае:

  • либо вы платите штраф понемногу, с каждой отдельной вставкой
  • , иначе вы заплатите больший штраф после того, как все вставки будут выполнены, но только один раз

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

Но кроме этого - никакой большой разницы, правда.

Марк

0
ответ дан 29 November 2019 в 00:04
поделиться

Я не планировал отвечать на этот вопрос, поскольку не уверен на 100% в своих знаниях. Но поскольку это не похоже на то, что вы получаете большой отклик ...

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

Итак, если вы уверены, что ваши данные чистые (без повторяющихся данных PK), я бы сказал вставить, а затем добавьте PK.

Но если в ваших данных могут быть дубликаты данных PK, я бы сказал, сначала создайте PK, чтобы он взорвался как можно скорее.

0
ответ дан 29 November 2019 в 00:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: