我的postgres数据库的SQL查询执行速度有问题。
我有两张桌子:
table 1: DEVICES
ID | NAME
------------------
1 | first device
2 | second device
table 2: DATA
ID | DEVICE_ID | TIME | DATA
--------------------------------------------
1 | 1 | 2016-07-14 2:00:00 | data1
2 | 1 | 2016-07-14 1:00:00 | data2
3 | 2 | 2016-07-14 4:00:00 | data3
4 | 1 | 2016-07-14 3:00:00 | data4
5 | 2 | 2016-07-14 6:00:00 | data5
6 | 2 | 2016-07-14 5:00:00 | data6
我需要获取此选择的结果表:
ID | DEVICE_ID | TIME | DATA
-------------------------------------------
4 | 1 | 2016-07-14 3:00:00 | data4
5 | 2 | 2016-07-14 6:00:00 | data5
即。对于设备表中的每个设备,我只需要获得一个具有最后TIME值的数据记录。
这是我的SQL查询:
SELECT * FROM db.data d
WHERE d.time = (
SELECT MAX(d2.time) FROM db.data d2
WHERE d2.device_id = d.device_id);
这是等效的HQL查询:
SELECT d FROM Data d
WHERE d.time = (
SELECT MAX(d2.time) FROM Data d2
WHERE d2.device.id = t2.device.id)
是的,我在我的项目中使用Hibernate ORM - 这个信息可能对某人有用。
我的查询得到了正确答案,但是时间太长了 - 数据表中的10k记录大约需要5-10秒,设备表中只有2个设备。太可怕了。
首先,我认为问题出在Hibernate中。但是linux终端中psql的本机sql查询与hibernate同时执行。
如何优化查询?此查询过于复杂:
O(device_count * data_count^2)
答案 0 :(得分:2)
由于您使用的是Postgres,您可以使用window functions来实现此目的,如下所示:
select
sq.id,
sq.device_id,
sq.time,
sq.data
from (
select
data.*,
row_number() over (partition by data.device_id order by data.time desc) as rnk
from
data
) sq
where
sq.rnk = 1
row_number()
窗口函数首先根据data
和device_id
列对time
表中的行进行排名,然后外部查询选择最高 - 排行。