SQL, объединяющий проблему производительности больших таблиц - PullRequest
0 голосов
/ 10 октября 2019

Существует структура реляционной базы данных с несколькими машинами. Каждый день машина будет иметь MachineActivity для этого дня. MachineActivity будет иметь до 24 часов HourHistory против него каждый день, HourHistory регистрирует несколько минут против часового периода до 60 минут, существуют ограничения на таблицу HourHistory, чтобы гарантировать, что 24 в час и 60 в минутах поддерживаются. Поэтому структура таблицы выглядит примерно так:

MACHINE
Id
MachineNumber

MACHINEACTIVITY
Id
MachineId
ActivityDate

HOURHISTORY
Id
MachineActivityId
Hour (0-23)
Minutes (0-60)

Я использую хранимую процедуру, чтобы попытаться вернуть строку для каждого MachineActivity, отсортировать часы по столбцам и вернуть минуты в этих столбцах, поэтомусмотреть на 24-часовой период и видеть минуты в каждом из часовых столбцов, например,

MachineActivity.Id |HourHistory.Hour1Minutes |HourHistory.Hour2Minutes и т. Д.

Я попробовал два способа сделать это в хранимой процедуре: сначала один раз объединить таблицу HourHistory и использовать несколько операторов CASE для вывода соответствующих HourMinutes, этосамый медленный по производительности:

SELECT 
    MA.ActivityDate,
    (CASE WHEN EHH."Hour" = 0 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes00,
    (CASE WHEN EHH."Hour" = 1 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes01,
    (CASE WHEN EHH."Hour" = 2 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes02,
    (CASE WHEN EHH."Hour" = 3 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes03,
    (CASE WHEN EHH."Hour" = 4 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes04,
    (CASE WHEN EHH."Hour" = 5 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes05,
    (CASE WHEN EHH."Hour" = 6 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes06,
    (CASE WHEN EHH."Hour" = 7 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes07,
    (CASE WHEN EHH."Hour" = 8 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes08,
    (CASE WHEN EHH."Hour" = 9 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes09,
    (CASE WHEN EHH."Hour" = 10 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes10,
    (CASE WHEN EHH."Hour" = 11 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes11,
    (CASE WHEN EHH."Hour" = 12 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes12,
    (CASE WHEN EHH."Hour" = 13 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes13,
    (CASE WHEN EHH."Hour" = 14 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes14,
    (CASE WHEN EHH."Hour" = 15 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes15,
    (CASE WHEN EHH."Hour" = 16 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes16,
    (CASE WHEN EHH."Hour" = 17 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes17,
    (CASE WHEN EHH."Hour" = 18 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes18,
    (CASE WHEN EHH."Hour" = 19 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes19,
    (CASE WHEN EHH."Hour" = 20 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes20,
    (CASE WHEN EHH."Hour" = 21 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes21,
    (CASE WHEN EHH."Hour" = 22 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes22,
    (CASE WHEN EHH."Hour" = 23 THEN EHH.EngineMinutes ELSE 0 END) AS HourMinutes23
FROM
    MachineActivity MA
LEFT JOIN
    HourHistory EHH ON EHH.MachineActivityId = MA.Id

Второй метод, который неожиданно дает лучший результат с точки зрения производительности, объединяет новую HourHistory для каждого из слотов Hour за день:

SELECT 
    MA.ActivityDate,
    ISNULL((EHH.EngineMinutes), 0) AS HourMinutes00,
    ISNULL((EHH1.EngineMinutes), 0) AS HourMinutes01,
    ISNULL((EHH2.EngineMinutes), 0) AS HourMinutes02,
    ISNULL((EHH3.EngineMinutes), 0) AS HourMinutes03,
    ISNULL((EHH4.EngineMinutes), 0) AS HourMinutes04,
    ISNULL((EHH5.EngineMinutes), 0) AS HourMinutes05,
    ISNULL((EHH6.EngineMinutes), 0) AS HourMinutes06,
    ISNULL((EHH7.EngineMinutes), 0) AS HourMinutes07,
    ISNULL((EHH8.EngineMinutes), 0) AS HourMinutes08,
    ISNULL((EHH9.EngineMinutes), 0) AS HourMinutes09,
    ISNULL((EHH10.EngineMinutes), 0) AS HourMinutes10,
    ISNULL((EHH11.EngineMinutes), 0) AS HourMinutes11,
    ISNULL((EHH12.EngineMinutes), 0) AS HourMinutes12,
    ISNULL((EHH13.EngineMinutes), 0) AS HourMinutes13,
    ISNULL((EHH14.EngineMinutes), 0) AS HourMinutes14,
    ISNULL((EHH15.EngineMinutes), 0) AS HourMinutes15,
    ISNULL((EHH16.EngineMinutes), 0) AS HourMinutes16,
    ISNULL((EHH17.EngineMinutes), 0) AS HourMinutes17,
    ISNULL((EHH18.EngineMinutes), 0) AS HourMinutes18,
    ISNULL((EHH19.EngineMinutes), 0) AS HourMinutes19,
    ISNULL((EHH20.EngineMinutes), 0) AS HourMinutes20,
    ISNULL((EHH21.EngineMinutes), 0) AS HourMinutes21,
    ISNULL((EHH22.EngineMinutes), 0) AS HourMinutes22,
    ISNULL((EHH23.EngineMinutes), 0) AS HourMinutes23   
FROM
    MachineActivity MA
LEFT JOIN
    HourHistory EHH ON EHH.MachineActivityId = MA.Id AND EHH."Hour" = 0
LEFT JOIN
    HourHistory EHH1 ON EHH1.MachineActivityId = MA.Id AND EHH1."Hour" = 1
LEFT JOIN
    HourHistory EHH2 ON EHH2.MachineActivityId = MA.Id AND EHH2."Hour" = 2
LEFT JOIN
    HourHistory EHH3 ON EHH3.MachineActivityId = MA.Id AND EHH3."Hour" = 3
LEFT JOIN
    HourHistory EHH4 ON EHH4.MachineActivityId = MA.Id AND EHH4."Hour" = 4
LEFT JOIN
    HourHistory EHH5 ON EHH5.MachineActivityId = MA.Id AND EHH5."Hour" = 5
LEFT JOIN
    HourHistory EHH6 ON EHH6.MachineActivityId = MA.Id AND EHH6."Hour" = 6
LEFT JOIN
    HourHistory EHH7 ON EHH7.MachineActivityId = MA.Id AND EHH7."Hour" = 7
LEFT JOIN
    HourHistory EHH8 ON EHH8.MachineActivityId = MA.Id AND EHH8."Hour" = 8
LEFT JOIN
    HourHistory EHH9 ON EHH9.MachineActivityId = MA.Id AND EHH9."Hour" = 9
LEFT JOIN
    HourHistory EHH10 ON EHH10.MachineActivityId = MA.Id AND EHH10."Hour" = 10
LEFT JOIN
    HourHistory EHH11 ON EHH11.MachineActivityId = MA.Id AND EHH11."Hour" = 11
LEFT JOIN
    HourHistory EHH12 ON EHH12.MachineActivityId = MA.Id AND EHH12."Hour" = 12
LEFT JOIN
    HourHistory EHH13 ON EHH13.MachineActivityId = MA.Id AND EHH13."Hour" = 13
LEFT JOIN
    HourHistory EHH14 ON EHH14.MachineActivityId = MA.Id AND EHH14."Hour" = 14
LEFT JOIN
    HourHistory EHH15 ON EHH15.MachineActivityId = MA.Id AND EHH15."Hour" = 15
LEFT JOIN
    HourHistory EHH16 ON EHH16.MachineActivityId = MA.Id AND EHH16."Hour" = 16
LEFT JOIN
    HourHistory EHH17 ON EHH17.MachineActivityId = MA.Id AND EHH17."Hour" = 17
LEFT JOIN
    HourHistory EHH18 ON EHH18.MachineActivityId = MA.Id AND EHH18."Hour" = 18
LEFT JOIN
    HourHistory EHH19 ON EHH19.MachineActivityId = MA.Id AND EHH19."Hour" = 19
LEFT JOIN
    HourHistory EHH20 ON EHH20.MachineActivityId = MA.Id AND EHH20."Hour" = 20
LEFT JOIN
    HourHistory EHH21 ON EHH21.MachineActivityId = MA.Id AND EHH21."Hour" = 21
LEFT JOIN
    HourHistory EHH22 ON EHH22.MachineActivityId = MA.Id AND EHH22."Hour" = 22
LEFT JOIN
    HourHistory EHH23 ON EHH23.MachineActivityId = MA.Id AND EHH23."Hour" = 23

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

Это большая проблема для меня, это занимает до 10 секунд, чтобывернуть данные, которые просто не достаточно быстры для конечных пользователей. Буду очень признателен за любые отзывы о том, как я могу повысить производительность.

1 Ответ

0 голосов
/ 10 октября 2019

Я предлагаю сначала отфильтровать ваши таблицы перед применением joins.

SELECT 
    MA.ActivityDate,
    ISNULL((EHH.EngineMinutes), 0) AS HourMinutes00,
    ISNULL((EHH1.EngineMinutes), 0) AS HourMinutes01,
    ISNULL((EHH2.EngineMinutes), 0) AS HourMinutes02,
    ISNULL((EHH3.EngineMinutes), 0) AS HourMinutes03,
    ISNULL((EHH4.EngineMinutes), 0) AS HourMinutes04,
    ISNULL((EHH5.EngineMinutes), 0) AS HourMinutes05,
    ISNULL((EHH6.EngineMinutes), 0) AS HourMinutes06,
    ISNULL((EHH7.EngineMinutes), 0) AS HourMinutes07,
    ISNULL((EHH8.EngineMinutes), 0) AS HourMinutes08,
    ISNULL((EHH9.EngineMinutes), 0) AS HourMinutes09,
    ISNULL((EHH10.EngineMinutes), 0) AS HourMinutes10,
    ISNULL((EHH11.EngineMinutes), 0) AS HourMinutes11,
    ISNULL((EHH12.EngineMinutes), 0) AS HourMinutes12,
    ISNULL((EHH13.EngineMinutes), 0) AS HourMinutes13,
    ISNULL((EHH14.EngineMinutes), 0) AS HourMinutes14,
    ISNULL((EHH15.EngineMinutes), 0) AS HourMinutes15,
    ISNULL((EHH16.EngineMinutes), 0) AS HourMinutes16,
    ISNULL((EHH17.EngineMinutes), 0) AS HourMinutes17,
    ISNULL((EHH18.EngineMinutes), 0) AS HourMinutes18,
    ISNULL((EHH19.EngineMinutes), 0) AS HourMinutes19,
    ISNULL((EHH20.EngineMinutes), 0) AS HourMinutes20,
    ISNULL((EHH21.EngineMinutes), 0) AS HourMinutes21,
    ISNULL((EHH22.EngineMinutes), 0) AS HourMinutes22,
    ISNULL((EHH23.EngineMinutes), 0) AS HourMinutes23   
FROM
    MachineActivity MA
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 0) EHH ON EHH.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 1) EHH1 ON EHH1.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 2) EHH2 ON EHH2.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 3) EHH3 ON EHH3.MachineActivityId = MA.Id
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 4) EHH4 ON EHH4.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 5) EHH5 ON EHH5.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 6) EHH6 ON EHH6.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 7) EHH7 ON EHH7.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 8) EHH8 ON EHH8.MachineActivityId = MA.Id
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 9) EHH9 ON EHH9.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 10) EHH10 ON EHH10.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 11) EHH11 ON EHH11.MachineActivityId = MA.Id
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 12) EHH12 ON EHH12.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 13) EHH13 ON EHH13.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 14) EHH14 ON EHH14.MachineActivityId = MA.Id
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 15) EHH15 ON EHH15.MachineActivityId = MA.Id
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 16) EHH16 ON EHH16.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 17) EHH17 ON EHH17.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 18) EHH18 ON EHH18.MachineActivityId = MA.Id
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 19) EHH19 ON EHH19.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 20) EHH20 ON EHH20.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 21) EHH21 ON EHH21.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 22) EHH22 ON EHH22.MachineActivityId = MA.Id 
LEFT JOIN
    (select EngineMinutes from HourHistory where "Hour" = 23) EHH23 ON EHH23.MachineActivityId = MA.Id 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...