目前,我正在使用RubyPStore
在磁盘上保存大对象(>1GB)不幸的是,PStore的大小似乎被限制在2GB左右,这对于我的应用程序来说是不够的。
然后我开始用postgres 9.5+postgis进行实验。这将允许存储更多的数据,并执行一些空间操作,我将需要在未来我在优胜美地的MacBook Pro(16GB)上使用pg-0.18.4。
令我惊讶的是(我不是数据库专家),性能上的损失是巨大的例如:
PStore磁盘写入:130.428481s
DB插件:4280.366986s
为了提供更多信息,这是我创建表的脚本:
CREATE TABLE public.radiation(
id integer NOT NULL,
time timestamp with time zone NOT NULL,
surface_total_shortwave double precision,
person_total_shortwave double precision,
mean_radiant_temperature double precision,
cell_id integer
) WITH ( OIDS=FALSE )
表中的每一行表示在某个时间(时间)的某个时刻网格(单元格id)的某个位置上的某个计算值。
INSERT
是(红宝石):INSERT INTO radiation (
id,
time,
surface_total_shortwave,
person_total_shortwave,
mean_radiant_temperature,
cell_id
) VALUES (
#{id},
'#{time}',
#{surface_total_shortwave},
#{person_total_shortwave},
#{mean_radiant_temperature},
#{cell_id}
)
根据这里的建议,所有键、索引、触发器等都被禁用所有
INSERT
都在一个事务中。如果查询更改为不是每个单元格id存储一行,而是存储完整数组(
double precision[]
),则INSERT
时间与PStore相当,但我失去了空间功能(我想)。我的问题是这正常吗性能能有什么提高吗可能是存储二进制数据?
直接用libpq切换到c有什么区别吗?
最佳答案
我在编码一个索引应用程序时遇到了同样的问题,第一次尝试用“AA>宝石”,但这对我来说没有效果。
通过使用SqLite解决了这个问题,SqLite能够处理内存中的数据库。
这里有一个例子,它使用的是activerecord(没有rails)。
ActiveRecord::Base.establish_connection(:adapter => "sqlite3",:database => "db/words.db")
unless ActiveRecord::Base.connection.table_exists?('words')
ActiveRecord::Schema.define do
create_table :words do |word_table|
word_table.column :word, :string
end
end
end
这里是我模型的一个类
class Word < ActiveRecord::Base
establish_connection(:adapter => "sqlite3",:database => ":memory:")
has_many :occurances
has_many :filenames, through: :occurances
end
索引部分(写作)使用这项技术在几千秒内写出数以千计的单词,阅读部分(用于网站)使用来自光盘的简单的Access。
不知道您使用的是哪种Ruby实现,但我通过使用MRI Ruby 2.364位(在Windows上)在其他地方解决了这个问题,它可以使用更多的内存,也可以使用jRuby,它可以提供额外的内存管理参数。
由于thsi类应用程序资源消耗大,性能很重要,因此最好将第一个解决方案与这些技术之一结合起来。
伊利亚的建议也很好,批量写,可以结合我的解决方案。
无论如何,重新思考你的算法,通常不需要通过优化来写那么多。
关于ruby - Ruby PStore与Postgres,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38293832/