减少具有未排序时间范围的表中的查询时间

Reducing query time in table with unsorted timeranges

本文关键字:时间 范围 查询 排序      更新时间:2023-10-16
几天

前我有一个关于这个问题的问题,但我仍然想知道如何调整我在这个查询上的表现。

我有一个看起来像这样的桌子(SQLite)

CREATE TABLE ZONEDATA (
TIME INTEGER  NOT NULL,
CITY INTEGER  NOT NULL,
ZONE INTEGER  NOT NULL,
TEMPERATURE DOUBLE,
SERIAL INTEGER ,
FOREIGN KEY (SERIAL) REFERENCES ZONES,
PRIMARY KEY ( TIME, CITY, ZONE));

我正在运行这样的查询:

SELECT temperature, time, city, zone from zonedata
WHERE (city = 1) and (zone = 1) and (time BETWEEN x AND y);

x 和 y 是变量,它们之间可能有几十万个变量。

温度范围从 -10.0 到 10.0,城市和区域从 0-20(在这种情况下是 1 和 2,但可以是其他东西)。从不同区域和城市以大约 5-6 秒的间隔连续记录记录。这会创建大量数据,并不一定意味着每条记录都按正确的时间顺序记录。

问题是我如何优化大时间范围内的记录检索(其中记录未按时间 100% 正确排序)。这可能需要很多时间,尤其是当我从几个城市和区域检索时。这意味着多次使用不同的参数运行提到的查询。我正在寻找的是查询、表结构(最好不是)或其他可更改设置的特定更改。

顺便说一句,我使用它的应用程序是用 c++ 实现的。

您的数据已经按Time排序。

通过(Time, City, Zone)具有主键,具有相同Time值的所有记录将彼此相邻。 (除非你在其他地方指定了 CLUSTER INDEX,尽管我对 SQLite 不够熟悉,不知道这是否可能。

但是,在您的特定情况下,这意味着您想要的记录彼此不相邻。 相反,他们是成群结队的。 每组记录将具有(city=1, zone=1)并具有相同的时间值。 一堆用于时间 1,另一束用于时间 2,依此类推。

这就像将所有内容放入 Excel 中并按时间、城市和区域排序。

要汇总您想要的所有记录(对于同一城市和区域),请将其更改为 (City, Zone, Time) .


但是请注意,如果您也查询all cities and zones but a time = ???我建议的密钥并不完美,那么您的原始密钥会更好。

因此,您可能希望/需要为不同的查询以不同的顺序添加不同的索引。


这意味着,为了给您一个特定的推荐解决方案,我们需要知道您将运行的特定查询。 我建议的键/索引顺序可能非常适合您的简化示例,但实际场景可能不同,足以保证完全不同的索引。

您可以为这些列编制索引,它将在内部对其进行排序以加快查询速度,但您不会看到它。

对于数据库between很难优化。 解决此问题的一种方法是添加额外的字段,以便您可以将between替换为 = 。 例如,如果添加day字段,则可以查询:

where  city = 1 and zone = 1 and day = '2012-06-22' and 
       time between '2012-06-22 08:00' and '2012-06-22 12:00'

此查询相对较快,索引位于 city, zone, day 上。

这需要考虑选择适当的额外字段。 它需要额外的代码来维护字段。 如果此查询位于应用程序的重要性能路径中,则可能值得。