Thank you kindly, this phrasing of the question is absolutely clear and detailed. The problem now is clear - You are preparing a single string with 16K rows, it will most certainly take ages to parse and prepare and is possibly the worst possible way to use SQLite. I'm not fluent in C++ so the following is a bit pseudo-code-ish, but the idea should be clear: The best way to do it would be to make the initial query so: ``` sql = "INSERT INTO KEYTABLE(FVIdx, hashkey) VALUES (?, ?);"; ``` Then prepare that query: ``` sqlite3_prepare_v3(pDB, sql, -1, SQLITE_PREPARE_PERSISTENT, &feat_stmt, NULL); ``` Then iterate your loop calling the sqlite3_bind_xxx functions every iteration and stepping the query to the next line, and finally, finalizing the query. Something like: ``` for (size_t idx = 0; idx < keyRowsPerInsert; ++idx) { sqlite3_bind_int(&feat_stmt, 1, idx); sqlite3_bind_int(&feat_stmt, 2, idx); // Or whatever other Key value you choose sqlite3_step(&feat_stmt); } sqlite3_finalize(&feat_stmt); ``` That should be faster than your current attempt by orders of magnitude. [More info on binding here](https://sqlite.org/cintro.html#binding_parameters_and_reusing_prepared_statements) [and here](https://sqlite.org/c3ref/bind_blob.html) [sqlite3_finalize info here](https://sqlite.org/c3ref/finalize.html) Note1: I seem to recall somewhere in the docs a rather succinct demonstration of the entire prepare-bind-step-finalize loop process, but cannot seem to locate it now. The above should be close enough to get you rolling. Note2: Your real code should involve some error checking testing return values from those calls to assess if they happened correctly or not. Those return codes are all documented.