我有两个表,conttagtable(t)和contfloattable(cf)。T 有大约 43k 行。CF拥有超过90亿。
tagindex我在两个表的列上创建了两个表的索引。可以将此列视为 for 的唯一标识符和 for的conttagtable外键。我没有在与另一个表相关的任何一个表上显式创建 PK 或外键,尽管此数据在逻辑上与两个表上的列相关,就像a和where a一样。数据来自微软访问转储,我不知道我是否可以相信 tagindex 是唯一的,因此不强制执行“唯一性”。conttagtableconfloattabletagindexconttagtable.tagindexPRIMARY KEYcontfloattable.tagindexFOREIGN KEY (tagindex) REFERENCES conttagtable(tagindex)
数据本身非常庞大。
我需要从contfloattable每个. 因此,如果给定的 4000 个样本跨越 30 分钟,我需要一个 0-14 分钟范围内的样本和一个 15-30 分钟范围内的样本。15 分钟范围内的任何一个样品都是可以接受的;第一个,最后一个,随机的,随便什么。contfloattable.dateandtimeconttagtable.tagidcontfloattabletagid
简而言之,我需要每 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