我将一些股票数据存储在Postgres 9.5数据库中,其中我的表格的格式如下(主日期,符号):
symbol (varchar[30]),
datetime (timestamptz),
value (double precision)
现在,我的一些较大的表超过8000万行,因此,有些查询比我想要的慢一些。 99%的查询都涉及为特定符号抓取一天的数据,例如:
SELECT * from "prices"
WHERE symbol = 'AAPl' AND datetime between '2016-07-22 9:30' AND '2016-07-22 16:30'
平均每天我会插入250k行,但在某些spikey天,它可以高达50万行。这是美国市场开放的6.5小时
我正在阅读分区并考虑每月进行分区(一个月平均20个交易日,每个分区应该有500到1000万行)
我对数据库没有经验,到目前为止我所设置的是新手的工作。在我编写自动分区脚本的过程中,看起来他们有一些类型的查询来查看分区是否存在。以下内容来自位于https://blog.engineyard.com/2013/scaling-postgresql-performance-table-partitioning
的更长的函数PERFORM 1
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND c.relname = _tablename
AND n.nspname = 'myschema';
我真的不想检查表格是否每天存在250k到500k次,所以我想我可以运行一个cron作业来按月创建表格然后不打扰检查?
我还在想,也许我应该将所有数据插入临时表,然后在市场收盘后于下午4:30运行cron作业,因为市场收盘后没有数据插入。我的想法是,我的cron作业将清空临时表并将所有内容放入正确的分区。
这值得吗?我应该考虑分片吗?数据库服务器是i7 6核心处理器,具有64 gig RAM和存储在SSD驱动器上的数据。我可以在同一台服务器上启动更多postgres实例,但我无法访问更多服务器,因此postgres实例必须存在于同一台服务器上。
另外,当我在这里的时候,我在桌子上应该有哪些关于索引的建议来使我的查询变得更快?
谢谢!
答案 0 :(得分:2)
Postgresql partitioning建立在表继承之上。在继续进行之前,您需要了解inheritance的这一限制。
继承功能的一个严重限制是索引 (包括唯一约束)和外键约束仅适用 单个表,而不是他们的继承子。这是真的 外键约束的引用和引用方。
如果你有幸不使用外键,可以使用是分区。
我不知道您在线阅读的内容,但如果您阅读official documentation,则分区很简单。对于新表来说这是真的。对于旧表来说,它有点棘手。我处理旧表的策略是这样的(它可能不是最好的):
1)创建newtable LIKE oldtable;
2)在newtable上创建分区
3)将数据移动到新表中
4)放下旧桌子并用视图替换它
5)创建触发器以使视图可写(这是非常标准的,您将在文档中找到示例)
不要创建太多分区,每月一个是合理的。
这不是分区的替代方法。这是你应该认真考虑的事情。你有symbol varchar(30)
为什么不创建一个名为symbols的表并将它们全部放在那里?那么你在这个表中只有一个int字段。假设平均符号长度为10,则表中每条记录将削减6个字节。该指数也将缩小,这有所帮助。
另一个优化是从double切换到int,这将节省另外4个字节(您必须以较小的货币格式存储价格)。有了这个和上面,我们减少了至少30%的表格大小!
我也在想,也许我应该插入我的所有数据 进入临时表,然后在市场收盘后运行一个cron工作 下午4:30,因市场收盘后没有数据插入。
几乎但并不完全。将所有内容插入主表。市场关闭后,使用cron作业将超过30天的数据移动到存档表中。
在追踪长期趋势时,您只需要高,低,收盘,开盘,您不需要日内波动。使用此数据创建汇总表(由您的cron填充)并将其用于趋势分析。仅将主表用于日内或短期趋势。