我有两个表,conttagtable
(t)和contfloattable
(cf)。T 有大约 43k 行。CF拥有超过90亿。
tagindex
我在两个表的列上创建了两个表的索引。可以将此列视为 for 的唯一标识符和 for的conttagtable
外键。我没有在与另一个表相关的任何一个表上显式创建 PK 或外键,尽管此数据在逻辑上与两个表上的列相关,就像a和where a一样。数据来自微软访问转储,我不知道我是否可以相信 tagindex 是唯一的,因此不强制执行“唯一性”。conttagtable
confloattable
tagindex
conttagtable.tagindex
PRIMARY KEY
contfloattable.tagindex
FOREIGN KEY (tagindex) REFERENCES conttagtable(tagindex)
数据本身非常庞大。
我需要从contfloattable
每个. 因此,如果给定的 4000 个样本跨越 30 分钟,我需要一个 0-14 分钟范围内的样本和一个 15-30 分钟范围内的样本。15 分钟范围内的任何一个样品都是可以接受的;第一个,最后一个,随机的,随便什么。contfloattable.dateandtime
conttagtable.tagid
contfloattable
tagid
简而言之,我需要每 15 分钟获取一个样本,但每个 t.tagname 只需要一个样本。现在的样本每 5 秒记录一次,数据跨越两年。就 sql 而言,这是一个大数据问题,而且超出了我的想象。我从谷歌搜索或搜索 SO 中尝试的所有时间间隔解决方案都产生了如此长的查询时间,以至于它们不实用。
- 我的索引是否足以进行快速连接?(它们似乎是在省略时间间隔部分时)
- 我会从添加任何其他索引中受益吗?
- 实现上述目标的最佳/最快查询是什么?
这是一个包含架构和一些示例数据的 SQLFiddle:http ://sqlfiddle.com/#!1/c7d2f/2
架构:
Table "public.conttagtable" (t)
Column | Type | Modifiers
-------------+---------+-----------
tagname | text |
tagindex | integer |
tagtype | integer |
tagdatatype | integer |
Indexes:
"tagindex" btree (tagindex)
Table "public.contfloattable" (CF)
Column | Type | Modifiers
-------------+-----------------------------+-----------
dateandtime | timestamp without time zone |
millitm | integer |
tagindex | integer |
Val | double precision |
status | text |
marker | text |
Indexes:
"tagindex_contfloat" btree (tagindex)
我想看到的输出是这样的:
cf.dateandtime |cf."Val"|cf.status|t.tagname
--------------------------------------------------
2012-11-16 00:00:02 45 S SuperAlpha
2012-11-16 00:00:02 45 S SuperBeta
2012-11-16 00:00:02 45 S SuperGamma
2012-11-16 00:00:02 45 S SuperDelta
2012-11-16 00:15:02 45 S SuperAlpha
2012-11-16 00:15:02 45 S SuperBeta
2012-11-16 00:15:02 45 S SuperGamma
2012-11-16 00:15:02 45 S SuperDelta
2012-11-16 00:30:02 45 S SuperAlpha
2012-11-16 00:30:02 45 S SuperBeta
2012-11-16 00:30:02 45 S SuperGamma
2012-11-16 00:30:02 45 S SuperDelta
2012-11-16 00:45:02 42 S SuperAlpha
……等等等等……
正如 Clodoaldo 所建议的,这是我的最新尝试,有什么建议可以加快速度吗?
with i as (
select cf.tagindex, min(dateandtime) dateandtime
from contfloattable cf
group by
floor(extract(epoch from dateandtime) / 60 / 15),
cf.tagindex
)
select cf.dateandtime, cf."Val", cf.status, t.tagname
from
contfloattable cf
inner join
conttagtable t on cf.tagindex = t.tagindex
inner join
i on i.tagindex = cf.tagindex and i.dateandtime = cf.dateandtime
order by floor(extract(epoch from cf.dateandtime) / 60 / 15), cf.tagindex
从上面查询计划: http: //explain.depesz.com/s/loR