或者我应该使用不同的锤子来解决这个问题。
我有一个非常简单的用例来存储数据,有效的稀疏矩阵,我试图存储在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 ),"Failed to build create statement"); checkdbres( sqlite3_step( pStmt ),sqlITE_DONE,"Failed to execute insert statement" ); checkdbres( sqlite3_finalize( pStmt ),"Failed to finalize insert"); checkdbres( sqlite3_prepare_v2( dbhandle,"create index issueidindex on data (issueid );","create index timeindex on data (time);","Failed to finalize insert"); for ( size_t idx=0; idx < nRecords; ++idx) { if (idx%800==0) { checkdbres( sqlite3_prepare_v2( dbhandle,"BEGIN TRANSACTION","Failed to begin transaction"); checkdbres( sqlite3_step( pStmt ),"Failed to execute begin transaction" ); checkdbres( sqlite3_finalize( pStmt ),"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,&pStmt,"Failed to build statement"); checkdbres( sqlite3_step( pStmt ),"Failed to execute insert statement" ); checkdbres( sqlite3_finalize( pStmt ),"Failed to finalize insert"); if (idx%800==799) { checkdbres( sqlite3_prepare_v2( dbhandle,"END TRANSACTION","Failed to end transaction"); checkdbres( sqlite3_step( pStmt ),"Failed to execute end transaction" ); checkdbres( sqlite3_finalize( pStmt ),"Failed to finalize end transaction"); } } checkdbres( sqlite3_close( dbhandle ),"Failed to close db" ); }
您是一次性插入所有800个元素吗?如果是,在事务中执行插入操作将大大加快进程。
原文链接:https://www.f2er.com/sqlite/198136.html见http://www.sqlite.org/faq.html#q19
sqlite可以处理非常大的数据库。见http://www.sqlite.org/limits.html