我想有一个简单的方法来运行查询,如以下查询我的时间序列数据:
"在彼此的七天内最典型的事件是什么?"
我可以通过利用SQL和Java程序来做到这一点,通过查看每一行并运行一个查询,查询提前七天查看所有事件,但这不是很优雅,性能会很糟糕.
我也得到了JNK和Milen A. Radev的帮助来编写以下SQL.我的问题是,当我在2300万行上测试它时,它运行了两个小时并停止,因为我的RamDisk(我运行PostgreSQL数据库)已满.你知道如何优化这样的查询吗?
SELECT a.eventID, b.eventID, COUNT(*)
FROM table a
INNER JOIN table b
ON a.eventID <> b.eventID
WHERE aBS(EXTRACT(EPOCH FROM (a.thetimeanddate - b.thetimeanddate))) < 5
GROUP BY a.eventID, b.eventID
ORDER BY COUNT(*) DESC
LIMIT 1000;
Run Code Online (Sandbox Code Playgroud)
部分问题是某些功能阻止RDBMS能够推断查询的某些属性,然后搜索任何索引.(查看SARGABLE了解更多相关信息.)
这意味着RDBMS必须处理每个事件组合并检查WHERE caluse以查看它们是否在彼此的5天内.每种组合相当于529,000,000,000,000种组合.(5.29亿是相当多的.)
如果您将查询重新设置为"WHERE b.thetimeanddate具有这些属性",那么您可能会发现性能提升.如果您的索引覆盖[thetimeanddate]字段,则会发生这种情况.例如...
SELECT
a.eventID,
b.eventID,
COUNT(*)
FROM
table a
INNER JOIN
table b
ON a.eventID <> b.eventID
WHERE
b.thetimeanddate >= date_trunc('day', a.thetimeanddate) - INTERVAL '5 days'
AND b.thetimeanddate < date_trunc('day', a.thetimeanddate) + INTERVAL '6 days'
GROUP BY
a.eventID,
b.eventID
ORDER BY
COUNT(*) DESC
LIMIT
1000
;
Run Code Online (Sandbox Code Playgroud)
现在,RDBMS应该能够更轻松地使用涵盖[thetimeanddate]字段的表上的任何索引.它现在只计算出你拥有的2900万个事件中每个事件的截断日期,并检查索引以查看在"此日期"和"该日期"之间出现的数量.可能比替代品快几百万倍......
(我也很想将WHERE子句移动到ON子句中,但仅用于样式目的.性能将是相同的.记住,RBDMS编译这些查询,并选择算法和优化.如果两个查询可以代数操作为了保持相同,他们通常会产生相同的最终执行计划.[假设操作所需的所有信息都存在于查询中,并且不是"只知道你的头脑".)
编辑
我还注意到你是通过a.eventID和b.eventID进行分组,然后进行计数.假设eventID在表中是唯一的,这将总是产生1 ...
编辑
将+5更改为+ INTERVAL'5天'
| 归档时间: |
|
| 查看次数: |
266 次 |
| 最近记录: |