Повышение производительности нескольких запросов на вставку и обновление - PullRequest
0 голосов
/ 07 мая 2019

У меня есть две таблицы: 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 две исходные и целевые таблицы снова, что стоит много времени.

Поэтому у меня есть идея:

  1. Я создам запрос, который сохраняет совпавшие строки между двумя таблицами (исходной и целевой) в таблицу temp_matched и сохраняет несопоставленные строки (не соответствующие целевой) в temp_nonmatched .

    В связи с этим у меня возникла проблема с запросом MERGE, поскольку в MERGE мы не можем сохранить данные в другую таблицу.

  2. Использовать 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)

1 Ответ

2 голосов
/ 07 мая 2019

Таблицы целей не имеют индекса.

Первое, что я хотел бы сделать, это проиндексировать таблицу целей на id и date.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...