【发布时间】:2020-02-07 13:39:15
【问题描述】:
有一个关系数据库结构,其中包含许多机器。在每一天,机器都会有当天的 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:
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 秒才能恢复数据,这对最终用户来说还不够快。任何有关如何提高性能的反馈都将不胜感激。
【问题讨论】:
-
这两个查询产生不同的结果集。
-
我没有收到不同的结果,你是什么意思?
标签: sql sql-server stored-procedures database-indexes