2013-08-07 63 views
0

我的sqlite數據庫只有一個表。這就是我要做的:創建一個包含一個表的數據庫,在該表中插入10,000條記錄,在某些列上創建所需的索引,然後關閉與數據庫的連接。我將記錄插入到事務中的數據庫中(在BEGIN和END之間)。我也在插入後創建索引以使插入操作更快。我的問題是:在執行COMMIT命令之前是否寫入了磁盤?我需要在內存上創建數據庫及其表格,在內存中再次插入記錄並創建索引,然後將所有數據一次性寫入遠程數據庫。我是否用下面的代碼實現了我的目的?如果不是,我該如何改進?在Sqlite中提交事務之前是否有任何磁盤I/O操作?

sqlite3 *db; 
    char *zErrMsg = 0; 
    int rc; 
    char sql[500]; 

    /* Open database */ 
    rc = sqlite3_open("test.db", &db); 
    if(rc){ 
     fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); 
     exit(0); 
    }else{ 
     fprintf(stderr, "Opened database successfully\n"); 
    } 

    rc = sqlite3_exec(db, "PRAGMA synchronous = OFF", NULL, NULL, &zErrMsg); 
    rc = sqlite3_exec(db, "PRAGMA journal_mode = MEMORY", NULL, NULL, &zErrMsg); 
    rc = sqlite3_exec(db, "BEGIN", NULL, 0, &zErrMsg); 

    sql = "CREATE TABLE MyTable (Col1 NUMERIC, Col2 NUMERIC, Col3 NUMERIC);"; 
    rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg); 

    /* Create SQL statement */ 
    for(int i=0; i<10000; i++) 
    { 
     sprintf(sql, "INSERT INTO MyTable (Col1, Col2, Col3, ..., ColN" 
        "VALUES (Val1, Val2, Val3, ..., ValN); "); 

     /* Execute SQL statement */ 
     rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); 

     if(rc != SQLITE_OK){ 
      fprintf(stderr, "SQL error: %s\n", zErrMsg); 
      sqlite3_free(zErrMsg); 
     }else{ 
      //fprintf(stdout, "Records created successfully\n"); 
     } 
    } 

    sql = "CREATE INDEX ix_Col1 ON MyTable(Col1 ASC);" 
     "CREATE INDEX ix_Col2 ON MyTable(Col2 ASC);"; 
    rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg); 

    rc = sqlite3_exec(db, "COMMIT", NULL, 0, &zErrMsg); 
    fprintf(stdout, "Records created successfully\n"); 
    sqlite3_close(db); 
+0

大型磁盤寫入永遠不會是原子性的。你真正的目標是什麼,爲什麼你認爲你可以通過在內存中構建數據庫來實現它? –

+0

@CL。我的目標是儘可能快地在數據庫中保存10,000條記錄。我也在考慮創建一個內存數據庫,然後將其保存到磁盤。 [http://www.sqlite.org/backup.html](http://www.sqlite.org/backup.html) – Meysam

回答

0

當SQLite的頁面緩存溢出時,即使在事務結束之前,已更改的數據也會寫入磁盤。 但是,這通常不是問題,因爲無論如何這些數據都必須寫入磁盤,並且如果需要再次讀取,它仍然在操作系統的文件緩存中。

如果你真的想增加頁面緩存大小,你可以使用PRAGMA cache_size。 但是如果這會產生任何影響,你必須測量自己。

相關問題