我正在分析扑克手的历史,并将数据存储在postgres数据库中。这是一个快速的 View :
我的性能相对较差,解析文件将花费几个小时。我可以看到数据库部分占用了总程序时间的97%。因此,只有一点点优化就可以使其更快。
我现在设置的方式如下:
由于我要为每个 Action ,每个 Action 序列,每个游戏发送查询,因此我显然进行了太多查询。我应该如何 bundle 它们以获得最佳性能?我不介意重写一些代码,所以不要退缩。 :)
提前致谢。
CX
最佳答案
没有任何查询,模式或Pg版本,很难回答这个问题。
但是,总的来说,解决这些问题的方法是将工作分成更大的更粗的批处理,以避免重复很多工作,最重要的是,一次完成所有工作。
关于事务,您还没有说什么,所以我想知道您是否在自动提交模式下完成所有这些操作。不好的计划。尝试将整个过程包装在BEGIN
和COMMIT
中。如果每隔几分钟/几十场游戏/等等,COMMIT
是一个长时间运行的过程,则编写一个检查点文件或DB条目,程序可以使用该条目或DB条目从该位置恢复导入,然后打开一个新事务进行。
在向同一表插入多行的地方,使用多值插入会有所帮助。例如:
INSERT INTO some_table(col1, col2, col3) VALUES
('a','b','c'),
('1','2','3'),
('bork','spam','eggs');
您可以使用
synchronous_commit=off
和commit_delay
来提高提交率,但是如果您将工作分批处理到更大的事务中,那并不是很有用。一个非常好的选择是将新数据插入
UNLOGGED
表(PostgreSQL 9.1或更高版本)或TEMPORARY
表(所有版本,但在 session 断开连接时丢失),然后在过程结束时将所有新行复制到主表并使用以下命令删除导入表:INSERT INTO the_table
SELECT * FROM the_table_import;
执行此操作时,
CREATE TABLE ... LIKE
很有用。另一个选择-确实是上述的更极端的版本-是在读取和转换结果时将结果写入CSV平面文件,然后将它们
COPY
放入数据库中。由于您使用的是C++,因此我假设您使用的是libpq
-在这种情况下,希望您也使用 libpqtypes
。 libpq
offers access to the COPY
api for bulk-loading,因此您的应用在生成CSV数据后,无需调出psql
即可加载CSV数据。关于c++ - 如何优化将此数据写入Postgres数据库,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12111327/