Скорость слияния и индексации SQL Server - PullRequest
0 голосов
/ 28 июля 2010

У меня есть оператор слияния, который нужно сравнивать по многим столбцам.Исходная таблица имеет 26 000 строк.Таблица назначения имеет несколько миллионов строк.Таблица десинтации имеет только типичный индекс первичного ключа для столбца типа int.

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

Merge Into desttable
Using #temptable
On 
(
desttable.ColumnA = #temptable.ColumnA  
and
desttable.ColumnB  =  #temptable.ColumnB  
and
desttable.ColumnC  = #temptable.ColumnC 
and
desttable.ColumnD  = #temptable.ColumnD 
and
desttable.ColumnE  = #temptable.ColumnE 
and
desttable.ColumnF  = #temptable.ColumnF
) 
When Not Matched Then  Insert Values (.......)

-- ColumnA: 167 unique values in #temptable
-- ColumnB: 1 unique values in #temptable
-- ColumnC: 13 unique values in #temptable
-- ColumnD: 89 unique values in #temptable
-- ColumnE: 550 unique values in #temptable
-- ColumnF: 487 unique values in #temptable

-- ColumnA: 3690 unique values in desttable
-- ColumnB: 3 unique values (plus null is possible) in desttable
-- ColumnC: 1113 unique values in desttable
-- ColumnD: 2662 unique values in desttable
-- ColumnE: 1770 unique values in desttable
-- ColumnF: 1480 unique values in desttable

Слияние сейчас занимает очень и очень много времени.Я думаю, что мне нужно изменить свой первичный ключ, но я не уверен, какая тактика может быть лучшей.26 000 строк могут быть вставлены при первом слиянии, но последующие слияния могут иметь только ~ 2000 вставок.Поскольку у меня нет индексов и только простой ПК, все идет медленно.:)

Кто-нибудь может указать, как сделать это лучше?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 28 июля 2010

Ну, очевидным кандидатом будет индекс для столбцов, которые вы используете для сопоставления в операторе MERGE - есть ли у вас индекс на (ColumnA, ColumnB, ColumnC, ColumnD, ColumnE, ColumnF) в вашей таблице назначения ??

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

Если нет: я бы попытался добавить его и посмотреть, как меняется поведение во время выполнения. MERGE теперь работает немного меньше, чем очень, очень долго ??

1 голос
/ 28 июля 2010

Мое предложение: если вам нужно запустить его только один раз, тогда утверждение слияния допустимо, если время не так критично.Но, если вы собираетесь использовать сценарий чаще, я думаю, что будет лучше, если вы будете делать это шаг за шагом вместо использования оператора Merge.Шаг за шагом, как создание собственных операторов выбора, вставки, обновления, удаления для достижения цели.Благодаря этому вы будете иметь больше контроля практически над всем (оптимизация запросов, индексация и т. Д.)

В вашем случае, вероятно, разделение 6, где критерии могут быть более эффективными, чем объединение их всех сразу.Недостатком является то, что у вас будет более длинный сценарий.

...