目前,我正在使用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/

10-09 09:23