【SQLite 3】3_sqlデータバインドメカニズム[共通ベース]
sql文実行プロセス:分析-コンパイル-実行
に質問
10000回の挿入操作を実行する場合、sql文は10000回「分析-コンパイル-実行」される必要があります.これは比較的効果的ではありません.例:
解決を試みる
バインドメカニズムを使用すると、sql文を一度だけ解析でき、その後の操作で最初に生成された実行計画が使用され、より高い実行効率が得られます.
手順:
に装備を施す
データのバインド
実行
ループ操作(バインド)の場合
レリーズ例:
プログラミング実験
出力:
に質問
10000回の挿入操作を実行する場合、sql文は10000回「分析-コンパイル-実行」される必要があります.これは比較的効果的ではありません.
char insert_sql[128] = {0};
for (int i=0; i<10000; ++i)
{
sprintf(insert_sql, "insert into bindtest values(%d, %d)", i, i*100);
ret = sqlite3_exec(ppdb, insert_sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf("insert fail
");
break;
}
sqlite3_free(errmsg);
}
解決を試みる
バインドメカニズムを使用すると、sql文を一度だけ解析でき、その後の操作で最初に生成された実行計画が使用され、より高い実行効率が得られます.
手順:
に装備を施す
int sqlite3_prepare(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
データのバインド
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
void(*)(void*));
int sqlite3_bind_double(sqlite3_stmt*, int, double);
int sqlite3_bind_int(sqlite3_stmt*, int, int);
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
void(*)(void*), unsigned char encoding);
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
実行
int sqlite3_step(sqlite3_stmt* mStmt);
ループ操作(バインド)の場合
int sqlite3_finalize(sqlite3_stmt *pStmt);
レリーズ
sqlite3_finalize(stmt);
sqlite3_stmt *pStmt = NULL;
char insert[] = "insert into bindtest values(?, ?)";
sqlite3_prepare(ppdb, insert, sizeof(insert), &pStmt, NULL);
// 2.
for (int i=0; i<10000; ++i)
{
sqlite3_bind_int(pStmt, 1, i); // , 1 !!!
sqlite3_bind_int(pStmt, 2, i * 100);
sqlite3_step(pStmt); //
sqlite3_reset(pStmt); //
}
// 3.
sqlite3_finalize(pStmt);
プログラミング実験
#include
#include
#include
int main()
{
// 1.
sqlite3 *ppdb = NULL;
int ret = sqlite3_open(":memory:", &ppdb);
if (ret != SQLITE_OK)
{
printf("open fail
");
return -1;
}
// 2. sql
// 2.1 create table apitest(id int, number int);
const char *create_sql = "create table if not exists bindtest(id int, number int)";
char *errmsg = NULL;
ret = sqlite3_exec(ppdb, create_sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf("%s
", errmsg);
}
sqlite3_free(errmsg);
// 2.2 ==============================
struct timeval start;
struct timeval end;
char insert_sql[128] = {0};
mingw_gettimeofday(&start, NULL);
for (int i=0; i<10000; ++i)
{
sprintf(insert_sql, "insert into bindtest values(%d, %d)", i, i*100);
ret = sqlite3_exec(ppdb, insert_sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf("insert fail
");
break;
}
sqlite3_free(errmsg);
}
mingw_gettimeofday(&end, NULL);
printf("nsert directly: %ld
", end.tv_usec - start.tv_usec);
// 2.3 ==============================
sqlite3_stmt *pStmt = NULL;
char insert[] = "insert into bindtest values(?, ?)";
mingw_gettimeofday(&start, NULL);
sqlite3_prepare(ppdb, insert, sizeof(insert), &pStmt, NULL);
for (int i=0; i<10000; ++i)
{
sqlite3_bind_int(pStmt, 1, i);
sqlite3_bind_int(pStmt, 2, i * 100);
sqlite3_step(pStmt);
sqlite3_reset(pStmt);
}
sqlite3_finalize(pStmt);
mingw_gettimeofday(&end, NULL);
printf("bind directly: %ld
", end.tv_usec - start.tv_usec);
// 3.
ret = sqlite3_close(ppdb);
if (ret != SQLITE_OK)
{
printf("close fail
");
return -1;
}
return 0;
}
出力:
nsert directly: 59873
bind directly: 27925