我不认为附加两个数据库并运行INSERT INTO foo (SELECT * FROM bar)
是最快的方法。如果您在手持设备和服务器(或其他设备)之间进行同步,传输机制是否会成为瓶颈?或者这两个数据库文件是否已经在同一个文件系统上?如果设备上的文件系统是较慢的闪存,这可能是瓶颈吗?
您是否能够在您的设备上编译/运行原始 SQLite C 代码?(我认为 RAW sqlite3 合并应该为 WinCE/Mobile 编译)如果是这样,你愿意:
- 编写一些 C 代码(使用 SQLite C API)
- 通过关闭磁盘日志来增加数据丢失的风险
应该可以编写一个小的独立可执行文件来非常快速地在两个数据库之间复制/同步 100K 记录。
我在这里发布了一些关于优化 SQLite 插入的知识: 提高 SQLite 的每秒插入性能?
编辑: 用真实的代码试过这个......
我不知道构建 Windows Mobile 可执行文件所涉及的所有步骤,但SQLite3 合并应该使用 Visual Studio 开箱即用地编译。这是一个示例main.c
程序,它打开两个 SQLite 数据库(两者必须具有相同的模式 - 请参阅#define TABLE
语句)并执行 SELECT 语句,然后将结果行绑定到 INSERT 语句:
/*************************************************************
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "sqlite3.h"
#define SOURCEDB "C:\\source.sqlite"
#define DESTDB "c:\\dest.sqlite"
#define TABLE "CREATE TABLE IF NOT EXISTS TTC (id INTEGER PRIMARY KEY, Route_ID TEXT, Branch_Code TEXT, Version INTEGER, Stop INTEGER, Vehicle_Index INTEGER, Day Integer, Time TEXT)"
#define BUFFER_SIZE 256
int main(int argc, char **argv) {
sqlite3 * sourceDB;
sqlite3 * destDB;
sqlite3_stmt * insertStmt;
sqlite3_stmt * selectStmt;
char * insertTail = 0;
char * selectTail = 0;
int n = 0;
int result = 0;
char * sErrMsg = 0;
clock_t cStartClock;
char sInsertSQL [BUFFER_SIZE] = "\0";
char sSelectSQL [BUFFER_SIZE] = "\0";
/* Open the Source and Destination databases */
sqlite3_open(SOURCEDB, &sourceDB);
sqlite3_open(DESTDB, &destDB);
/* Risky - but improves performance */
sqlite3_exec(destDB, "PRAGMA synchronous = OFF", NULL, NULL, &sErrMsg);
sqlite3_exec(destDB, "PRAGMA journal_mode = MEMORY", NULL, NULL, &sErrMsg);
cStartClock = clock(); /* Keep track of how long this took*/
/* Prepared statements are much faster */
/* Compile the Insert statement */
sprintf(sInsertSQL, "INSERT INTO TTC VALUES (NULL, @RT, @BR, @VR, @ST, @VI, @DT, @TM)");
sqlite3_prepare_v2(destDB, sInsertSQL, BUFFER_SIZE, &insertStmt, &insertTail);
/* Compile the Select statement */
sprintf(sSelectSQL, "SELECT * FROM TTC LIMIT 100000");
sqlite3_prepare_v2(sourceDB, sSelectSQL, BUFFER_SIZE, &selectStmt, &selectTail);
/* Transaction on the destination database */
sqlite3_exec(destDB, "BEGIN TRANSACTION", NULL, NULL, &sErrMsg);
/* Execute the Select Statement. Step through the returned rows and bind
each value to the prepared insert statement. Obviously this is much simpler
if the columns in the select statement are in the same order as the columns
in the insert statement */
result = sqlite3_step(selectStmt);
while (result == SQLITE_ROW)
{
sqlite3_bind_text(insertStmt, 1, sqlite3_column_text(selectStmt, 1), -1, SQLITE_TRANSIENT); /* Get Route */
sqlite3_bind_text(insertStmt, 2, sqlite3_column_text(selectStmt, 2), -1, SQLITE_TRANSIENT); /* Get Branch */
sqlite3_bind_text(insertStmt, 3, sqlite3_column_text(selectStmt, 3), -1, SQLITE_TRANSIENT); /* Get Version */
sqlite3_bind_text(insertStmt, 4, sqlite3_column_text(selectStmt, 4), -1, SQLITE_TRANSIENT); /* Get Stop Number */
sqlite3_bind_text(insertStmt, 5, sqlite3_column_text(selectStmt, 5), -1, SQLITE_TRANSIENT); /* Get Vehicle */
sqlite3_bind_text(insertStmt, 6, sqlite3_column_text(selectStmt, 6), -1, SQLITE_TRANSIENT); /* Get Date */
sqlite3_bind_text(insertStmt, 7, sqlite3_column_text(selectStmt, 7), -1, SQLITE_TRANSIENT); /* Get Time */
sqlite3_step(insertStmt); /* Execute the SQL Insert Statement (Destination Database)*/
sqlite3_clear_bindings(insertStmt); /* Clear bindings */
sqlite3_reset(insertStmt); /* Reset VDBE */
n++;
/* Fetch next from from source database */
result = sqlite3_step(selectStmt);
}
sqlite3_exec(destDB, "END TRANSACTION", NULL, NULL, &sErrMsg);
printf("Transfered %d records in %4.2f seconds\n", n, (clock() - cStartClock) / (double)CLOCKS_PER_SEC);
sqlite3_finalize(selectStmt);
sqlite3_finalize(insertStmt);
/* Close both databases */
sqlite3_close(destDB);
sqlite3_close(sourceDB);
return 0;
}
在我的 Windows 桌面机器上,这段代码在 1.20 秒内复制了 100k 条记录source.sqlite
。dest.sqlite
我不知道你会在带有闪存的移动设备上看到什么样的性能(但我很好奇)。