1

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

我有一个看起来像这样的表(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++ 中实现的。

4

3 回答 3

1

您的数据已经按 排序Time

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

但是,在您的特定情况下,这意味着您想要的记录彼此不相邻。相反,它们是成束的。每组记录都将具有(city=1, zone=1)相同的时间值。一组用于 Time1,另一组用于 Time2,以此类推。

这就像把所有东西都放在 Excel 中,然后按时间排序,然后按城市排序,然后按区域排序。

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


但是请注意,如果您还对all cities and zones but a time = ???我建议的密钥进行查询,那么您的原始密钥会更好。

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


这意味着要为您提供特定的推荐解决方案,我们需要知道您将运行的特定查询。我建议的键/索引顺序对于您的简化示例可能是理想的,但实际情况可能不同,足以保证完全不同的索引。

于 2012-06-22T10:47:10.020 回答
0

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

于 2012-06-22T10:40:18.887 回答
0

因为数据库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.

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

于 2012-06-22T10:50:52.297 回答