【问题标题】:Lightweight in-memory database轻量级内存数据库
【发布时间】:2013-01-08 15:09:28
【问题描述】:

我们的一个需求是创建一个临时内存数据库,然后执行各种插入/选择/更新。

一目了然,SQLite 满足了我们的所有需求。与内存中 SQLite DB 的连接可以很简单地建立:

class SQLiteBase < ActiveRecord::Base
  self.abstract_class = true

  establish_connection(adapter:  'sqlite3', database: ':memory:')
end

不久前,当我们发现需要将数据批量加载(特别是批量插入)到 SQLite 表中时,我们开始研究一些性能问题(请参阅these 基准测试)。

不幸的是,SQLite 似乎不支持批量插入。

那么是否还有其他基于 SQL 的轻量级内存数据库,支持批量插入

如果没有——有没有办法利用重量级数据库,如 PostreSQL(MySQL 或任何其他主要参与者)作为内存数据库

如果 postresql/mysql 不是一种可行的方法 - 是否有任何其他 C 高度优化的数据结构以及基于它的查询语言? (有/没有红宝石绑定)。

【问题讨论】:

  • 在这些测试中,您是否在内存数据库中正确使用事务?

标签: ruby-on-rails sqlite query-optimization


【解决方案1】:

首先,SQLite 确实支持使用以下方法进行批量插入:

  • 穷人对多值INSERT的替代:

    INSERT INTO mytable (a,b,c) SELECT 1 a, 2 b, 'x' c 
                      UNION ALL SELECT 2,   5,   'y' 
                      UNION ALL SELECT 3,   7,   'z'
                  ...
    
  • 真正的多值插入,自 SQLite 3.7.11 起支持:

    INSERT INTO mytable (a,b,c) VALUES (1,2,'x'),
                                       (2,5,'y'),
                                       (3,7,'z');
    
  • 使用交易:

    BEGIN;
    INSERT INTO mytable (a,b,c) VALUES (1,2,'x');
    INSERT INTO mytable (a,b,c) VALUES (2,5,'y');
    INSERT INTO mytable (a,b,c) VALUES (3,7,'z');
    COMMIT;
    

如果你问如何将这些翻译成 Ruby 或 Ruby on Rails - 我承认,我不知道,但我想应该可以。

但是,即使 SQLite 不支持这些方法,对于内存数据库来说,这一切都无关紧要 - 因为如果它真的全部在内存中,插入速度不应该真正取决于你是逐行插入还是作为一项交易。您的速度限制实际上只是原始内存复制带宽。

【讨论】:

  • 谢谢你,mvp。事实上,从 3.7.11 开始,SQLite 支持具有多个值的批量 INSERT。 sqlite.org/changes.html。虽然我怀疑它和你的第一个例子差不多
  • 当我第一次写我的答案时,我想包含多值插入,因为我可以发誓我成功使用它,但在测试时它不起作用。事实证明,我在使用 SQLite 3.7.10 的机器上对其进行了测试。最近的 SQLite 确实支持多值插入 - 我已经更新了我的答案。
【解决方案2】:

【讨论】:

    【解决方案3】:

    事实证明,从 3.7.11 开始,SQLite 支持批量插入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-20
      • 2011-05-25
      • 2016-01-20
      相关资源
      最近更新 更多