dwe*_*lus 5 sql sql-server pivot-table
我在使用特定的SQL行到列转换时遇到严重的性能问题.单个查询最多需要一分钟才能获得6小时的数据.为了清晰起见,我简化了下面的表格,但是每天有超过一百万的数据点,因此表格大小可能有所贡献.我对这样的复杂查询没有多少经验,所以我想要一些建议.数据表如下......
(DataPoint表)
id datetime
_____________________
1 2015-09-08 21:00:00
2 2015-09-08 21:00:01
3 2015-09-08 21:00:02
4 2015-09-08 21:00:03
5 2015-09-08 21:00:04
Run Code Online (Sandbox Code Playgroud)
(SensorData表)
id datapointId SensorId Temp DateTime
_____________________________________________________
1 1 20 34.6 2015-09-08 21:00:00.345
2 1 21 34.2 2015-09-08 21:00:00.551
3 1 22 34.1 2015-09-08 21:00:00.101
4 1 41 34.3 2015-09-08 21:00:00.700
5 2 20 34.2 2015-09-08 21:00:01.223
6 2 21 34.4 2015-09-08 21:00:01.456
7 2 22 34.5 2015-09-08 21:00:01.100
8 2 41 34.6 2015-09-08 21:00:01.870
Run Code Online (Sandbox Code Playgroud)
请注意,单个传感器DateTime和DataPoint DateTime不相等(但它们很接近).这就是为什么我使用第二个表来让我能够进行粗略的并排比较而无需做一些模糊的dateTime逻辑.
我需要使用看起来像这样的结果数据集来查询此信息...
DateTime Temp1 Temp2 Temp3
__________________________________________________
2015-09-08 21:00:00 34.5 34.1 41.1
2015-09-08 21:00:01 34.4 34.2 41.2
2015-09-08 21:00:02 34.4 34.2 41.2
Run Code Online (Sandbox Code Playgroud)
我当前的SQL查询是(动态)编写的......
SELECT DataPoint.DateTime,
max(case when SensorData.SensorId = 20 then SensorData.Temp end) Temp1,
max(case when SensorData.SensorId = 21 then SensorData.Temp end) Temp2,
max(case when SensorData.SensorId = 22 then SensorData.Temp end) Temp3,
FROM DataPoint LEFT JOIN SensorData ON DataPoint.Id=dbo.SensorData.DataPointId
WHERE DataPoint.DateTime BETWEEN [x] and [y]
GROUP BY DataPoint.DateTime ORDER BY DataPoint.DateTime
Run Code Online (Sandbox Code Playgroud)
所以我的问题有三个部分:
1)为什么这个特定的查询这么慢?
2)有没有更好的方法来存储我丢失的信息?此时我还处于设计阶段.我选择了这种模式,因为我需要能够比较传感器的时间序列信息,这些传感器会以不规则的间隔发射数据.
3)有没有更快的方法来查询和翻译这些数据到我想要的格式?
编辑!!!对不起,我的查询结尾有一个GroupBy子句,我忘了添加.我的错.
首先,您需要确保有索引DataPointId,如果那是PK可能有索引,但如果是,则FK必须手动添加它。
SensorId其次,您需要和 的索引DateTime
SensorID在查询之前第三次过滤现在您正在处理所有百万条记录以生成报告
。
WHERE SensorID IN (20,21,22)
Run Code Online (Sandbox Code Playgroud)
您也可以尝试一下PIVOT功能
SELECT [DateTime], [20] as Temp1, [21] as Temp2, [22] as Temp3
FROM
(SELECT [DateTime], SensorId, [Temp]
FROM sensor) AS SourceTable
PIVOT
(
MAX([Temp])
FOR SensorId IN ([20], [21], [22])
) AS PivotTable;
Run Code Online (Sandbox Code Playgroud)