我有两个表:bal1和bal2遵循相同的结构:
CREATE TABLE bal1
( ts timestamp without timezone,
bid double precision,
ask double precision
CONSTRAINT bal1_pkey PRIMARY KEY (ts)
);
CREATE TABLE bal2
( ts timestamp without timezone,
bid double precision,
ask double precision
CONSTRAINT bal2_pkey PRIMARY KEY (ts)
);
''列是主键。
NB:bal1& bal2每行有15,000,000行。
我想要请求2个表的并集,按时间戳排序。 所以我执行:
SELECT t.ts, t.bid, t.ask
FROM
((SELECT ts, bid, ask FROM bal1 ORDER BY ts ASC)
union
(SELECT ts, bid, ask FROM bal2 ORDER BY ts ASC)) t
ORDER BY t.ts ASC
但是这个请求需要一个无限的时间来返回数据:在核心i7,6GB,7200 t / m磁盘上大约需要10分钟。 我希望添加" ORDER BY"子句将帮助db引擎...但它没有。
问题:如何让事情变得更快?你认为问题来自:
我毫不犹豫地将所有数据放在一个表中,并且productid integer
列代表product1和product2。
sql请求可能是:
SELECT productid, ts, bid, ask
FROM bal
WHERE productid=1 or productid=2
ORDER BY ts ASC
这种修改对我来说非常耗时,所以在以这种方式提交之前我会建议你。
最后一件事:我计划添加更多产品(3,4,5等),因此请求应该能够快速响应,尽管有几个UNION阻止...
答案 0 :(得分:3)
order by
没有帮助 SQL引擎。它只是增加了额外的工作。此外,union
必须删除重复项。
您可能会发现使用适当的索引可以更快,更快地执行此操作:
SELECT ts, bid, ask
FROM bal1
UNION ALL
SELECT ts, bid, ask
FROM bal2 b2
WHERE NOT EXISTS (SELECT 1 FROM bal1 b1 WHERE b1.ts = b2.ts and b1.bid = b2.bid and b1.ask = b2.ask)
当然,这不会删除表中的重复项。如果需要,则应将distinct
添加到两个selects
。
此指数为bal1(ts, bid, ask)
。
如果需要,您可以在查询中添加order by ts
。这需要额外的时间进行处理。
答案 1 :(得分:1)
你在这里解决他的错误问题 - 你的问题不是订单。它使用错误的技术开始。
首先,拥有多个表是没有意义的 - 如果必须使用数据库(ouch)并在其上放置适当的索引,则将所有表存储在一起。硬件 - 6GB内存不会持续,而不是7200RPM sata光盘。在多个SSD上进行Raid 0可以通过处理帮助您处理订单,但这是一个破碎的设计。
在此处做类似的事情,并在http://www.trade-robots.com/blog/how-to-efficiently-store-and-read-tick-data
上发表博文基本上:
我的backtest集群每秒吞噬6-7千兆位数据,而且没有延迟问题。也就是说,我在10千兆网络上运行它,数据来自带有SSD缓存的Raid 10中的8个速龙。文件服务器是一个限制为8GB内存的虚拟机。因此,可以获得不错的结果,但您必须使用正确的工具。我决定反对数据库,但有时间序列的(也是免费的)特殊数据库 - 只是不是一个普通的关系数据库,而且最重要的是没有一个有这么糟糕的设计(为什么一个联盟开始?)
对于没有人认为这是一个答案的人 - 确实如此。这种方法解决了核心问题。这不是工会表现。在这种情况下,它试图将一个盒子装入一个圆孔。