在Sqlite中提交事务之前是否有任何磁盘I / O操作?

时间:2013-08-07 07:40:55

标签: performance sqlite transactions disk-io

我的sqlite数据库只有一个表。这就是我要做的:创建数据库,其中包含一个表,在该表中插入10,000条记录,在某些列上创建所需的索引,然后关闭与数据库的连接。我将记录插入到事务中的数据库中(在BEGIN和END之间)。我也在插入后创建索引以使插入操作更快。我的问题是:在执行COMMIT命令之前是否有任何内容写入磁盘?我需要在内存上创建数据库及其表,在内存中再次插入记录和创建索引,然后立即将所有数据写入dist。我是否通过以下代码实现了我的目的?如果没有,我该如何改进呢?

   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);

1 个答案:

答案 0 :(得分:0)

当SQLite的页面缓存溢出时,即使在事务结束之前,更改的数据也会写入磁盘。 但是,这通常不是问题,因为无论如何都必须将数据写入磁盘,如果需要再次读取它仍然在操作系统的文件缓存中。

如果您确实想要增加页面缓存大小,可以使用PRAGMA cache_size。 但是如果这会产生任何影响,你必须衡量自己。