2014-11-05 35 views
0

我有两个表:以下相同的结构和BAL1 BAL2:大表格和UNION表演

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) 
); 

“ts”的列是主键。

注意: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 

但这请求采用无限的时间来返回数据:〜10分钟一个核i7,6GB 7200 T/M的磁盘。 我希望添加“ORDER BY”子句将有助于数据库引擎...但它没有。

问题:如何让事情变得更快?你认为问题来自:

  1. 表结构不适合UNION选择种类?
  2. 从sql请求?
  3. 从db本身? Postgres适合这种用法吗?使用Oracle或MySql更好吗?

我毫不犹豫地把所有的数据放在一张表中,而productid integer列代表了product1和product2。 的SQL请求比可能是:

SELECT productid, ts, bid, ask 
FROM bal 
WHERE productid=1 or productid=2 
ORDER BY ts ASC 

这种修改是耗时的我,所以我想你以这种方式commiting之前建议。

最后一件事:我计划增加更多的产品(3,4,5等),因此请求应该能够尽管几个UNION块蛮快的回应...

+0

为什么您需要查询返回3000万行数据? – mustaccio 2014-11-05 16:09:05

+0

对db中可用的整个历史数据运行backtest。数据本身永远不会在内存中同时完全加载。 sql-return-set将被流式传输。 – norisknofun 2014-11-05 16:12:32

+0

嗯,下面是你要做的:*获得一些明智的光盘,*获得一些合理的RAM,*摆脱联盟,因为他们滥用关系模型,*意识到你需要一个教训。联合和顺序将所有结果转储到临时数据库空间。你的硬盘吓坏了,并且必须预定所有的结果。 – TomTom 2014-11-05 16:47:56

回答

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添加到查询中。这将需要额外的时间进行处理。

+0

可能是这是我的问题:我没有希望UNION删除数据!不要紧,如果数据有'ts'双重。 – norisknofun 2014-11-05 16:42:36

+0

除了已经说过的内容之外,由于您正在读取整个表,因此数据库引擎可以做的很少,以便优化它:您受磁盘和内存吞吐量的限制。 – mustaccio 2014-11-05 17:03:38

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内存的虚拟机。所以,有可能获得不错的结果,但你必须使用正确的工具。我决定使用数据库,但是有时间序列的特殊数据库(也就是免费的) - 只是不是一个普通的关系数据库,而且没有一个具有这样一个破碎的设计(为什么联合起步?)

对于任何人不要以为这是一个答案 - 它是。这种方法解决了核心问题。这不是联盟的表现。在这种情况下,它试图将一个盒子放入一个圆孔中。

+0

我没有这方面的资源。这就是为什么一个分贝。 – norisknofun 2014-11-05 16:44:51

+0

您的意思是您没有使用LESS资源的解决方案的资源,因此您将资源分配给使用更多资源的db所没有的资源?在调试过程中,我会在1.5秒内纯粹读取我工作站上一周的数据。这是所有出价/要求的ES数据。我用比你少的资源。错误的技术。 – TomTom 2014-11-05 16:46:34