У меня есть две процедуры вставки SQL в фабрику данных Azure. Первый - вставить изменения, а второй - вставить новые строки в случае, если они обнаружены, что их нет в новых CSV-файлах. В особенности вторая процедура вставки слишком медленная.
В качестве фона в таблице dbo.reservations2 содержится около 50-100 тысяч ежедневных строк. И таблицы, которые вставляются, варьируются от 200 тысяч до 2 миллионов строк. В настоящее время первая процедура занимает около 2,5 минут, что вполне нормально. Но второй, кажется, занимает несколько часов. Требуемая скорость для второго будет меньше одного часа.
Для дальнейшего уточнения существует 3 типа временных горизонтов: один с 7 днями, второй с 14 днями и последний с 30 днями в будущем. Обновление 30 дней приходит только один раз в день, 14 дней в час и 7 дней каждые 15 минут. Для обновления 30 дней есть временной интервал, в котором больше ничего не происходит в течение примерно 1,5 часов каждое утро
Я пробовал следующие индексы, хотя не уверен, что они помогают. По крайней мере, вторая на самом деле замедляла вставку первой процедуры при тестировании (хотя возможности Explain в студии данных Azure предлагали это).
CREATE NONCLUSTERED INDEX reservations_date_custom on dbo.reservations2 (datetime) include (dv_id, dv_datahash, id, unit, room, duration, specialist, specialisation1, specialisation2, specialisation3, timetype)
CREATE NONCLUSTERED INDEX reservations_date_custom2 on dbo.reservations2 (datetime) include (dv_datahash, dv_load_time, id)
CREATE NONCLUSTERED INDEX staging_id on staging.reservations (id)
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[dv_insert]
AS
INSERT INTO
dbo.reservations2 (
dv_id,
dv_datahash,
dv_load_time,
dv_expir_time,
id,
unit,
room,
datetime,
duration,
specialist,
specialisation1,
specialisation2,
specialisation3,
timetype,
reserved
)
SELECT
dv_id,
dv_datahash,
dv_load_time,
dv_expir_time,
id,
unit,
room,
datetime,
duration,
specialist,
specialisation1,
specialisation2,
specialisation3,
timetype,
reserved
FROM (
SELECT
CONVERT(VARCHAR(32), HashBytes('MD5', UPPER(ISNULL(id, '-1'))), 2) AS dv_id,
CONVERT(VARCHAR(32), HashBytes('MD5', UPPER(ISNULL(CAST(id AS nvarchar(max)), '-1') + '~' + ISNULL(CAST(unit AS nvarchar(max)), '-1') + '~' + ISNULL(CAST(room AS nvarchar(max)), '-1') + '~' + ISNULL(CAST(datetime AS nvarchar(max)), '-1') + '~' + ISNULL(CAST(duration AS nvarchar(max)), '-1') + '~' + ISNULL(CAST(specialist AS nvarchar(max)), '-1') + '~' + ISNULL(CAST(specialisation1 AS nvarchar(max)), '-1') + '~' + ISNULL(CAST(specialisation2 AS nvarchar(max)), '-1') + '~' + ISNULL(CAST(specialisation3 AS nvarchar(max)), '-1') + '~' + ISNULL(CAST(timetype AS nvarchar(max)), '-1') + '~' + ISNULL(CAST(reserved AS nvarchar(max)), '-1'))), 2) AS dv_datahash,
GETDATE() AS dv_load_time,
null as dv_expir_time,
id AS id,
unit AS unit,
room AS room,
datetime AS datetime,
duration AS duration,
specialist AS specialist,
specialisation1,
specialisation2,
specialisation3,
timetype AS timetype,
reserved AS reserved
FROM staging.reservations2) t1
WHERE t1.dv_datahash NOT IN (
Select dv_datahash
From (Select dv_datahash, row_number() over(partition by id order by dv_load_time desc) as ranking
from dbo.reservations2
Where datetime >= (Select min([datetime]) from staging.reservations2)) as t2
Where t2.ranking = '1'
)
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[dv_insert_deleted]
AS
INSERT INTO
dbo.reservations2 (
dv_id,
dv_datahash,
dv_load_time,
dv_expir_time,
id,
unit,
room,
datetime,
duration,
specialist,
specialisation1,
specialisation2,
specialisation3,
timetype,
reserved
)
SELECT
dv_id,
dv_datahash,
dv_load_time,
dv_expir_time,
id,
unit,
room,
datetime,
duration,
specialist,
specialisation1,
specialisation2,
specialisation3,
timetype,
reserved
FROM (
SELECT
dv_id,
dv_datahash,
Getdate() AS dv_load_time,
null as dv_expir_time,
id,
unit,
room,
datetime,
duration,
specialist,
specialisation1,
specialisation2,
specialisation3,
timetype,
2 AS reserved
FROM dbo.reservations2) t3
WHERE t3.[datetime] >= (Select min([datetime]) from staging.reservations2)
AND t3.[datetime] <= (Select max([datetime]) from staging.reservations2)
AND t3.id NOT in(
SELECT distinct id
FROM staging.reservations2)
AND t3.id Not in(
Select id
From (Select reserved, id, row_number() over(partition by id order by dv_load_time desc) as ranking
from dbo.reservations2
Where datetime >= (Select min([datetime]) from staging.reservations2)
AND datetime <= (Select max([datetime]) from staging.reservations2)) as t2
Where t2.ranking = '1'
AND reserved = '2')