Hallo list, I'm relatively inexperienced when it comes to databases and SQL (but to programming). I'm using sqlite's (recent version) C API called from a C++ application.
I'm confronted with the following situation: Ca. 2500-3000 objects (called 'entity') everyone with 3 properties (REAL in sqlite notation) depending on 'positions' (x,y,z). (x,y,z) are INTEGERS, the grid size might slightly vary between the entities. The database in a first attempt looks like: EntityTable key val1 val2 .... 1 2 . . 2500 MatrixTable key key_to_entitytable x y z prop1 prop2 prop2 1 1 0 0 0 . . . . 1 0 0 1 . . . . 1 0 0 2 . . . . . . . . . . . 25*10^6 . . . . . . . My problem is the second table. Appending all 25*10^6 rows takes 40 minutes on a PC with 3 GHz, 1GB memory and sufficient large harddisk. 1) On a technical level, my usage of the sqlite API might be improper. So I'll attach the relevant code encapsulating the appends : The sql() functions utilizes more or less sqlite_exec + error handling, but has no impact here. table ... name of the sqlite table stmtmatrix ... vector of rows ('BindRecord's' - 25 million for the mentioned case) void Database::append(const QString& table, const vector<BindRecord>& stmtmatrix, bool skipprimarykey /*=true*/) { if (stmtmatrix.empty()) return; QString pstr("insert into "); pstr += table + " values ("; if (skipprimarykey) pstr += "NULL, "; pstr += "?"; for (unsigned i=1; i!=stmtmatrix[0].values.size(); ++i) { pstr += ",?"; } pstr += ")"; int c = 0; sql("begin"); sqlite3_stmt *stmt; if (sqlite3_prepare( db_, pstr.ascii(), // stmt -1, &stmt, 0 )!= SQLITE_OK) { printf("\nCould not prepare statement."); return; } for (unsigned i=0; i!=stmtmatrix.size(); ++i) // iterating rows { for (unsigned j = 0; j!=stmtmatrix[i].values.size(); ++j) { int ERR = sqlite3_bind_text ( stmt, j+1, // Index of wildcard stmtmatrix[i].values[j].ascii(), stmtmatrix[i].values[j].length(), // length of text SQLITE_STATIC ); if (ERR != SQLITE_OK) { printf("\nCould not prepare statement."); } } sqlite3_step(stmt); sqlite3_reset(stmt); ++c; if (c==100000) { sql("commit"); sql("begin"); c=0; } } sql("commit"); sqlite3_finalize(stmt); } Calling Database::.sql("PRAGMA synchronous = OFF") before Database::append improves speed, but not beyond the 40 minutes cited. Can someone elaborate on the code regarding performance ? 2) Database design. Is this big table a good choice or has anyone recommendations for better design. For example, splitting the big table into smaller ones (assigned to a single entity) with ~100000 rows and later on building database requests utilizing joints ? Or something completely different ? Thank you, Micha --