У меня есть две таблицы: Sale_Source
(10.000 строк) и Sale_Target
(1 миллиард строк).У меня четыре запроса к INSERT
и UPDATE
Sale_Target
с данными из Sale_Source
.
- Исходная таблица имеет некластеризованный индекс на
id
и Date
- Целевая таблица имеет индексы на
id
и Date
, но я отключил их, чтобы повысить производительность
Запросы
ВСТАВИТЬ запрос № 1:
INSERT INTO dbo.Sale_Target (id, Salevalue, Salestring, Date)
SELECT id, Salevalue, Salestring, Date
FROM dbo.Sale_Source s
WHERE NOT EXISTS (SELECT 1 FROM dbo.Sale_Target t ON s.id = t.id)
ОБНОВЛЕНИЕ запроса # 1 (если даты совпадают):
UPDATE t
SET t.Salevalue = s.Salevalue,
t.Salestring = s.Salestring
FROM dbo.Sale_Source s
JOIN dbo.Sale_Target t ON t.id = s.id AND s.Date = t.Date
WHERE t.Salevalue <> s.Salevalue OR t.Salestring <> s.Salestring
ОБНОВЛЕНИЕ запроса № 2 (когда дата в SaleSource> Дата в SaleTarget):
UPDATE t
SET t.Salevalue = s.Salevalue,
t.Salestring = s.Salestring
FROM dbo.Sale_Source s
JOIN dbo.Sale_Target t ON t.id = s.id AND s.Date > t.Date
ОБНОВЛЕНИЕ запроса # 3 (когда идентификатор в источнике равен null
в join
предложении):
UPDATE t
SET t.Salevalue = null,
t.Salestring = null
FROM dbo.Sale_Source s
LEFT JOIN dbo.Sale_Target t ON t.id = s.id
WHERE s.id IS NULL
Четыре запроса требуют 1 час.30 минутдо конца, что очень медленно для исходной таблицы с только 10.000 строк.Я думаю, что проблема здесь в том, что каждый раз, когда выполняется четыре запроса, им нужно JOIN
две исходные и целевые таблицы снова, что стоит много времени.
Поэтому у меня есть идея:
Я создам запрос, который сохраняет совпавшие строки между двумя таблицами (исходной и целевой) в таблицу temp_matched и сохраняет несопоставленные строки (не соответствующие целевой) в temp_nonmatched .
В связи с этим у меня возникла проблема с запросом MERGE
, поскольку в MERGE
мы не можем сохранить данные в другую таблицу.
Использовать temp_nonmatched в запросе INSERT
, в запросе UPDATE
.Я заменю таблицу Sale_Source на temp_matched .
Есть ли у вас какие-либо идеи сделать это или мы можем оптимизировать эти четыре запроса другим способом??
Спасибо.
Определение таблицы:
CREATE TABLE [dbo].[Sale_Target](
[id] [numeric](8, 0) NOT NULL,
[Salevalue] [numeric](8, 0) NULL,
[Salestring] [varchar](20) NULL,
[Date] [Datetime2](7) NULL
) ON [PRIMARY]
CREATE NONCLUSTERED COLUMNSTORE INDEX "NCCI_Sale_Target"
ON [dbo].[Sale_Target] (id,Date)
CREATE TABLE [dbo].[Sale_Source](
[id] [numeric](8, 0) NOT NULL,
[Salevalue] [numeric](8, 0) NULL,
[Salestring] [varchar](20) NULL,
[Date] [Datetime2](7) NULL
) ON [PRIMARY]
CREATE NONCLUSTERED COLUMNSTORE INDEX "NCCI_Sale_Source"
ON [dbo].[Sale_Target] (id,Date)