У меня есть метод вставки SQL на определенный момент времени, который требует некоторого ускорения - PullRequest
0 голосов
/ 11 ноября 2019

У меня есть две процедуры вставки 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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...