优化事件表的SQL查询

问题描述 投票:0回答:1

在SQLite中,db是一个表,其中包含事件,可以及时记录对某个实体的更改。

有数千个这些实体,其参数随时间变化,因此在每次更改时,我们都会记录更改的时间步长和整个参数集。

例如

------------------------------------
| NodeId | tStep | Param1 | Param2 |
------------------------------------
|   1    |  92   |  90    |  20.8  |
|   5    |  92   |  101   |  -2.4  |
|   5    |  108  |  38    |  -3.6  |
------------------------------------

我需要在特定时间点检索实体的状态,例如,在tStep == 100我应该有NodeId 1, Param1 == 90NodeId 5, Param1 == 101而在tStep == 110我应该有NodeId 1, Param1 == 90NodeId 5, Param1 == 38

以下Select工作正常,但我需要优化数据库,以便尽快检索结果。

SELECT NodeId, tStep, Param1, Param2, MAX(tStep) FROM EventsTable
WHERE tStep <= ?
GROUP BY NodeId;

唯一的限制是我不能为每个tstep设置实体状态,因为它会使db变得庞大。

我可以添加索引和其他帮助表。


预期(和有效)结果:

-------------------------------------------------
| NodeId | tStep | Param1 | Param2 | Max(TStep) |
-------------------------------------------------  
|  1     |  92   |  90    |   20.8 | 92         |
|  5     | 108   |  90    |     0  |  108       |
-------------------------------------------------
sql database sqlite optimization indexing
1个回答
0
投票

您的查询有效,因为SQLite恰好保证非标准行为并且不受任何其他数据库支持。此外,有人在查询中添加了min(tstep)。我强烈建议不要依赖这个(误)功能。

你应该这样做:

select et.*
from eventstable et
where et.tstep < ?
order by et.tstep desc
limit 1;

对于此查询,您需要eventstable(tstep)上的索引。

编辑:

如果您需要所有节点ID:

select et.*
from eventstable et
where et.tstep = (select max(et2.tstep)
                  from eventstable et2
                  where et2.nodeid = et.nodeid and et.tstep < ?
                 );

对于此版本,您需要eventstable(nodeid, tstep)上的索引。

© www.soinside.com 2019 - 2024. All rights reserved.