SQLite能处理9千万条记录吗?

或者我应该使用不同的锤子来解决这个问题。

我有一个非常简单的用例来存储数据,有效的稀疏矩阵,我试图存储在SQLite数据库。我创建了一个表:

create TABLE data ( id1 INTEGER KEY, timet INTEGER KEY, value REAL )

其中我插入了大量的数据,(每10分钟800个元素,每天45次),一年中的大部分日子。 (id1,timet)的元组将始终是唯一的。

时间值是自纪元以来的秒,并且将始终增加。出于所有实际目的,id1是随机整数。可能只有20000个唯一的ID。

然后我想访问所有的值,其中id1 == someid或访问所有元素,其中timet ==有时。在我在Linux上使用最新的SQLite通过C接口测试,查找其中之一(或任何变体的这种查找)大约需要30秒,这不够快,我的用例。

我尝试定义一个索引的数据库,但这减慢了插入到完全不可行的速度(我可能已经做错了,但…)

上表导致任何数据的访问速度非常慢。我的问题是:

>是SQLite完全错误的工具吗?
>我可以定义指标来加快速度吗?
>我应该使用类似HDF5而不是SQL吗?

请原谅我对SQL的基本了解!

谢谢

我包括一个代码示例,显示了在使用索引时,插入速度如何减慢。使用“create index”语句,代码需要19分钟完成。没有它,它运行在18秒。

#include <iostream>
#include <sqlite3.h>

void checkdbres( int res, int expected, const std::string msg ) 
{
  if (res != expected) { std::cerr << msg << std::endl; exit(1); } 
}

int main(int argc, char **argv)
{
  const size_t nRecords = 800*45*30;

  sqlite3      *dbhandle = NULL;
  sqlite3_stmt *pStmt = NULL;
  char statement[512];

  checkdbres( sqlite3_open("/tmp/junk.db", &dbhandle ), SQLITE_OK, "Failed to open db");

  checkdbres( sqlite3_prepare_v2( dbhandle, "create table if not exists data ( issueid INTEGER KEY, time INTEGER KEY, value REAL);", -1, & pStmt, NULL ), SQLITE_OK, "Failed to build create statement");
  checkdbres( sqlite3_step( pStmt ), SQLITE_DONE, "Failed to execute insert statement" );
  checkdbres( sqlite3_finalize( pStmt ), SQLITE_OK, "Failed to finalize insert");
  checkdbres( sqlite3_prepare_v2( dbhandle, "create index issueidindex on data (issueid );", -1, & pStmt, NULL ), SQLITE_OK, "Failed to build create statement");
  checkdbres( sqlite3_step( pStmt ), SQLITE_DONE, "Failed to execute insert statement" );
  checkdbres( sqlite3_finalize( pStmt ), SQLITE_OK, "Failed to finalize insert");
  checkdbres( sqlite3_prepare_v2( dbhandle, "create index timeindex on data (time);", -1, & pStmt, NULL ), SQLITE_OK, "Failed to build create statement");
  checkdbres( sqlite3_step( pStmt ), SQLITE_DONE, "Failed to execute insert statement" );
  checkdbres( sqlite3_finalize( pStmt ), SQLITE_OK, "Failed to finalize insert");

  for ( size_t idx=0; idx < nRecords; ++idx)
  {
    if (idx%800==0)
    {
      checkdbres( sqlite3_prepare_v2( dbhandle, "BEGIN TRANSACTION", -1, & pStmt, NULL ), SQLITE_OK, "Failed to begin transaction");
      checkdbres( sqlite3_step( pStmt ), SQLITE_DONE, "Failed to execute begin transaction" );
      checkdbres( sqlite3_finalize( pStmt ), SQLITE_OK, "Failed to finalize begin transaction");
      std::cout << "idx " << idx << " of " << nRecords << std::endl;
    }

    const size_t time = idx/800;
    const size_t issueid = idx % 800;
    const float value = static_cast<float>(rand()) / RAND_MAX;
    sprintf( statement, "insert into data values (%d,%d,%f);", issueid, (int)time, value );
    checkdbres( sqlite3_prepare_v2( dbhandle, statement, -1, &pStmt, NULL ), SQLITE_OK, "Failed to build statement");
    checkdbres( sqlite3_step( pStmt ), SQLITE_DONE, "Failed to execute insert statement" );
    checkdbres( sqlite3_finalize( pStmt ), SQLITE_OK, "Failed to finalize insert");

    if (idx%800==799)
    {
      checkdbres( sqlite3_prepare_v2( dbhandle, "END TRANSACTION", -1, & pStmt, NULL ), SQLITE_OK, "Failed to end transaction");
      checkdbres( sqlite3_step( pStmt ), SQLITE_DONE, "Failed to execute end transaction" );
      checkdbres( sqlite3_finalize( pStmt ), SQLITE_OK, "Failed to finalize end transaction");
    }
  }

  checkdbres( sqlite3_close( dbhandle ), SQLITE_OK, "Failed to close db" ); 
}
您是一次性插入所有800个元素吗?如果是,在事务中执行插入操作将大大加快进程。

http://www.sqlite.org/faq.html#q19

SQLite可以处理非常大的数据库。见http://www.sqlite.org/limits.html

http://stackoverflow.com/questions/3160987/can-sqlite-handle-90-million-records

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:SQLite能处理9千万条记录吗?