2016-07-29 2 views
0

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

INSERT INTO [dbo].[Transactions_Refined] 
    SELECT 
     Client_ID, 
     Customer_ID, 
     Transaction_ID, 
     SUM(try_parse(value_sold AS numeric(18,2))) AS value_sold, 
     SUM(try_parse(quantity AS numeric(18,4))) AS quantity, 
     subclass, 
     article, 
     try_parse(Transaction_Date AS Datetime) AS Transaction_Date, 
     Store_ID 
    FROM 
     [dbo].[Transaction_Dump] 
    GROUP BY 
     Client_ID, Customer_ID, Transaction_ID, 
     try_parse(Transaction_Date AS Datetime), 
     subclass, article, Store_ID ; 

WITH cte AS 
(
    SELECT 
     *, 
     row_number() OVER(PARTITION BY Client_ID, Customer_ID, Transaction_ID, value_sold, quantity, subclass, article 
         ORDER BY Client_ID, Customer_ID, Transaction_ID, value_sold, quantity, subclass, article) AS [rn] 
    FROM 
     [dbo].[Transactions_Refined] 
    WHERE 
     Client_ID IN (SELECT DISTINCT [Client_ID] 
        FROM [dbo].[Transaction_Dump])) 
DELETE cte 
WHERE [rn] > 1 ; 

Я хотел бы ускорить процесс. Есть идеи? Я думаю об использовании внешнего соединения.

+0

Is Transaction_Dump таблица, которую вы загружаете из какого-либо текстового файла? Это причина, по которой вы используете TRY_PARSE? Сколько записей обычно содержит? И сколько записей содержит Transactions_Refined? Является ли это совокупной таблицей, к которой вы присоединяетесь и которая постоянно растет? Я вижу, что вы используете ROW_NUMBER для удаления дубликатов ключей, но разве вы не теряете информацию таким образом? –

+0

Замените 'IN DISTINCT' на' EXISTS' –

+0

To: tomislav_t Да, данные поступают из текстового файла, и я разбираю его, потому что мне нужно преобразовать его в правильные форматированные данные. Я не использую SSIS, я использую Azure Data Factory. Да, у меня это есть, я добавляю данные. Нет, я не теряю информацию, которая мне нужна. –

ответ

1

Код импортирует данные из текстового файла в Transaction_Dump. GROUP BY в первом заявлении заботится об объединении отдельных транзакций с помощью Client_ID, Customer_ID, Transaction_ID, Transaction_Date, подкласса, статьи, Store_ID и суммы value_sold и количества.

Агрегированные записи вставляются в Transaction_Refined. Мы предполагаем, что этот процесс повторяется периодически, так что в конечном итоге Transaction_Refined станет очень большим.

После вставки в Transaction_Refined возникают некоторые нежелательные дубликаты. Эти дубликаты удаляются с помощью инструкции DELETE с помощью CTE. CTE охватывает оператор DELETE, он выбирает записи из Transaction_Refined с ClientId, которые были упомянуты в последнем Transaction_Dump.

Я подозреваю, что код ошибки указан выше. Агрегация во вставке имеет место среди других в StoreId и Transaction_Date. Это имеет смысл.

Странно, что код DELETE удаляет дубликаты, не группируя StoreId и Transaction_Date для ClientId, которые произошли в последнем Transaction_Dump.

Важным вопросом является то, является ли использование ClientId уникальным для файла Transaction_Dump. Я бы предположил, что это неверно, т. Е. Один ClientId может иметь несколько заказов в разные дни.

Вышеуказанный оператор DELETE в основном потеряет Transaction_Refined records, поскольку он игнорирует StoreId и Transaction_Date.

Есть два способа решить эту проблему:

Вариант 1: Вы лечить Transaction_Refined как агрегированная таблица, где вы храните операции агрегируются в день. В этом случае мы могли бы сделать оператор DELETE и CTE устаревшим, удалив дубликаты во вставке.

Вариант 2: Вы рассматриваете Transaction_Refined как вид общей суммы транзакций для каждого клиента по всем StoreId и Transaction_Date. Если это так, то столбцы StoreId и Transaction_Date должны быть удалены из таблицы Transaction_Refined, и для обеспечения правильности агрегации должен быть код для новых записей INSERT или UPDATE существующих записей.

Следующим шагом будет решение, хотите ли вы перейти на вариант 1 или вариант 2. После этого вам будет легко сделать очень эффективный TSQL-код для обновления таблицы Transaction_Refined.

Смежные вопросы