我一直在努力在我的C++程序中更快地获得sqlite。我相信结果与预期的相去甚远。
我的数据库中有几张表,其中大多数都有几条记录,而其中有很多记录(4986450)。达到此大小确实很困难,因为每个事务的插入量过多,并且插入速度很慢。
另一方面,现在我要在该大表上进行简单查询,例如
sqlite3_prepare_v2(db,"SELECT * FROM Table where primary_key=?1;",-1, &query,NULL);
sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &sErrMsg);
....
while(running){
sqlite3_bind_text(query, 1, pkey.c_str(), (int)pkey.size() , SQLITE_STATIC);
int query_status = sqlite3_step(query);
if(query_status == SQLITE_ROW){
data = sqlite3_column_int(query,1);
(... just saving data in a map)
}
}
sqlite3_exec(db, "END TRANSACTION", NULL, NULL, &sErrMsg);
(为简单起见,我更改了表和列的名称)。
该查询会在很短的时间内完成,并在同一事务中完成很多次。选择查询大约需要500秒才能完成9秒钟。即使当我将数据插入表中时,我也可以得到更好的体验。
我在数据库上有以下编译指示
PRAGMA main.page_size = 4096;
PRAGMA main.cache_size=10000;
PRAGMA main.locking_mode=EXCLUSIVE;
PRAGMA main.synchronous=OFF;
PRAGMA main.journal_mode=WAL;
PRAGMA main.cache_size=5000;
您能帮我调整数据库吗?我究竟做错了什么?
最佳答案
选项一:
没有整数主键而不是字符串的可能性-它确实会破坏SELECT性能。
选项二:
该表有几列,您的记录集中是否需要所有这些列?如果您可以腾出时间读取和复制数据,则可能会获得更好的结果。
选项三:
有没有可能重写由sqlite3_step代替人工外部控制所控制的循环?在记录集上进行迭代(偶尔跳过未使用的行)比每次重新选择新的记录集要好很多。将数据保存到 map 表明这应该可行。