2013. 2. 19. 11:06
sqlite의 stmt를 재활용(sqlite3_reset)하여 성능 향상 시키기 (sqlite3 query, insert 예제)
2013. 2. 19. 11:06 in 프로그래밍/Let's Share it
sqlite3를 사용하여 Insert나 Query할 때 아래와 같은 방법으로 사용할 수 있습니다.
(리턴값 체크는 필수이지만, 간략하게 표시하기 위해 제외하였습니다)
(1) sqlite3_exec을 통해 SQL문을 그대로 만들어 전달하고, query는 callback 함수를 통해 전달 받음
int fnCallback(void* arg, int columns, wchar_t** value, wchar_t** name) { ... } ... for (...) { ... // DB QUERY sqlite3_exec(db, "SELECT ...", fnCallback, pContext, NULL); ... // DB INSERT sqlite3_exec(db, "INSERT ...", NULL, NULL, NULL); ... |
... sqlite3_stmt* pStmt = NULL; ... for (...) { // DB INSERT sqlite3_finialize(pStmt); sqlite3_prepare(db, "INSERT ... (?,?)", -1, &pStmt, NULL); sqlite3_bind_int(pStmt, 1, 123); sqlite3_bind_int(pStmt, 2, 456); sqlite3_step(pStmt); sqlite3_finalize(pStmt); pStmt = NULL; ... // DB QUERY sqlite3_prepare(db, "SELECT a,b,c ... WHERE a=? AND b=?", -1, &pStmt, NULL); sqlite3_bind_int(pStmt, 1, 111); sqlite3_bind_int(pStmt, 2, 333); for (;;) { if (SQLITE_ROW == sqlite3_step(pStmt)) { nA = sqlite3_column_int(pStmt, 0); nB = sqlite3_column_int(pStmt, 1); nC = sqlite3_column_int(pStmt, 2); } else { break; } } sqlite3_finalize(pStmt); pStmt = NULL; ... |
... sqlite3_stmt* pStmtInsert = NULL; sqlite3_stmt* pStmtQuery = NULL; ... sqlite3_prepare(db, "INSERT ... (?,?)", -1, &pStmtInsert, NULL); sqlite3_prepare(db, "SELECT a,b,c ... WHERE a=? AND b=?", -1, &pStmtQuery, NULL); ... for (...) { // DB INSERT sqlite3_reset(pStmtInsert); sqlite3_bind_int(pStmtInsert, 1, 123); sqlite3_bind_int(pStmtInsert, 2, 456); sqlite3_step(pStmtInsert); ... // DB QUERY sqlite3_reset(pStmtQuery); sqlite3_bind_int(pStmtQuery, 1, 111); sqlite3_bind_int(pStmtQuery, 2, 333); for (;;) { if (SQLITE_ROW == sqlite3_step(pStmtQuery)) { nA = sqlite3_column_int(pStmtQuery, 0); nB = sqlite3_column_int(pStmtQuery, 1); nC = sqlite3_column_int(pStmtQuery, 2); } else { break; } } ... } ... sqlite3_finalize(pStmtInsert); pStmtInsert = NULL; sqlite3_finalize(pStmtQuery); pStmtQuery = NULL; ... |
(2)과 (3)의 차이는 sqlite3_prepare(...)의 호출 빈도라 할 수 있습니다. (3)에서는 그 자리에 대신 sqlite3_reset(...)이 들어가 있습니다. 해당 코드를 보면 sqlite3_reset이 훨씬 부하가 적어 보입니다(단순히 memory free 위주로 되어 있음). 물론 sqlite3_prepare는 btree 호출도 있고 구문 parsing도 있습니다. 위 예에서는 누락되어 있지만, sqlite3_reset의 리턴값 체크는 해주는 것이 중요합니다.
'프로그래밍 > Let's Share it' 카테고리의 다른 글
mongoose와 visual studio c++를 가지고 web application 만들기 (2) | 2013.07.24 |
---|---|
메모리 출력(memory dumper, memory print) 공유 (1) | 2013.04.04 |
SQLite 암호화(encrypt) 지원하기 (SQLITE_HAS_CODEC) (30) | 2012.06.20 |
간단하게 SHA256(sha2) 구하기 (1) | 2012.05.25 |
PE 포맷 바이너리 파일의 버전을 구하는 함수 (0) | 2012.04.30 |