【发布时间】:2014-09-09 13:06:57
【问题描述】:
我有一个包含许多测量设备的系统。这些测量值存储在表“sample_data”中。 每台设备一年内可能进行 1000 万次测量。大多数情况下,用户只对特定时期内等间隔内的 100 分钟最大配对感兴趣,例如过去 24 小时或过去 53 周。为了得到这 100 分钟和最大值,周期被分成 100 个相等的间隔。从每个间隔中提取最小值和最大值。您会推荐最有效的数据查询方法吗?到目前为止,我已经尝试了以下查询:
WITH periods AS (
SELECT time.start AS st, time.start + (interval '1 year' / 100) AS en
FROM generate_series(now() - interval '1 year', now(), interval '1 year' / 100) AS time(start)
)
SELECT s.* FROM sample_data s
JOIN periods ON s.time BETWEEN periods.st AND periods.en
JOIN devices d ON d.customer_id = 23
WHERE
s.id = (SELECT id FROM sample_data WHERE device_id = d.id and time BETWEEN periods.st AND periods.en ORDER BY sample ASC LIMIT 1) OR
s.id = (SELECT id FROM sample_data WHERE device_id = d.id and time BETWEEN periods.st AND periods.en ORDER BY sample DESC LIMIT 1)
此查询大约需要 4 秒。它不是很合适,因为 sample_data 表每个设备最多可以包含 10M 行。 我看到它运行的方式不是非常优化,但不知道为什么。我以为我已经索引了这个查询中使用的所有关键字段。
您能推荐我一种更快地获取此类统计信息的方法吗?
表“设备”:
Column | Type | Modifiers
--------------------+-----------------------------+------------------------------------------------------
id | integer | not null default nextval('devices_id_seq'::regclass)
customer_id | integer |
<Other fields skipped as they are not involved into the query>
Indexes:
"devices_pkey" PRIMARY KEY, btree (id)
"index_devices_on_iccid" UNIQUE, btree (iccid)
查询中指定的 customer_id = 23,它有 12 个设备,只有 4 个设备。
表“sample_data”:
Column | Type | Modifiers
----------------+-----------------------------+----------------------------------------------------------
id | integer | not null default nextval('sample_data_id_seq'::regclass)
sample | numeric | not null
time | timestamp without time zone | not null
device_id | integer | not null
customer_id | integer | not null
Indexes:
"sample_data_pkey" PRIMARY KEY, btree (id)
"sample_data_device_id_time_sample_idx" btree (device_id, "time", sample)
它有大约 170 万行。每个属于 customer_id = 23 的 4 个设备大约有 720K 行。 该表现在由测试数据填充。
“选择版本()”结果:
PostgreSQL 9.3.5 on x86_64-apple-darwin13.3.0, compiled by Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn), 64-bit
track_io_timing 设置为“开启”
在此处解释(分析,缓冲区)结果: http://explain.depesz.com/s/kA12
【问题讨论】:
标签: sql postgresql