Есть ли какая-либо операция ввода-вывода диска, выполненная до того, как транзакция будет зафиксирована в Sqlite?

Моя база данных sqlite имеет только одну таблицу. Вот что я собираюсь сделать: создать базу данных с одной таблицей внутри, вставить 10000 записей в эту таблицу, создать необходимые индексы в некоторых столбцах, а затем закрыть соединение с базой данных. Я вставляю записи в базу данных в рамках транзакции (между BEGIN и END). Я также создаю индексы после вставки, чтобы ускорить операцию вставки. Мой вопрос: что-нибудь записывается на диск до того, как я выполню команду COMMIT? Мне нужно создать базу данных и ее таблицу в памяти, вставить записи и снова создать индексы в памяти, а затем сразу записать все данные в дистрибутив. Я достигаю своей цели с помощью следующего кода? Если нет, как я могу улучшить это?

   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 ответ

При переполнении кэша страниц SQLite измененные данные записываются на диск еще до завершения транзакции. Однако обычно это не является проблемой, поскольку эти данные в любом случае должны быть записаны на диск, и они все еще находятся в файловом кеше операционной системы, если их нужно будет снова прочитать.

Если вы действительно хотите увеличить размер кэша страницы, вы можете использовать PRAGMA cache_size. Но вы должны измерить себя, если это будет иметь значение.

Другие вопросы по тегам