SQLite๋ฅผ ์ต์ ํํ๋ ๊ฒ์ ๊น๋ค ๋กญ์ต๋๋ค. C ์ดํ๋ฆฌ์ผ์ด์ ์ ๋๋ ์ฝ์ ์ฑ๋ฅ์ ์ด๋น 85 ๊ฐ์ ์ฝ์ ์์ ์ด๋น 96,000 ์ด์์ ์ฝ์ ๊น์ง ๋ค์ํฉ๋๋ค!
๋ฐฐ๊ฒฝ : ๋ฐ์คํฌํฑ ์์ฉ ํ๋ก๊ทธ๋จ์ ์ผ๋ถ๋ก SQLite๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ด๊ธฐํ ๋ ๋ ์ถ๊ฐ ์ฒ๋ฆฌ๋ฅผ ์ํด ๊ตฌ๋ฌธ ๋ถ์๋์ด SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก๋ก๋๋๋ XML ํ์ผ์ ๋ง์ ์์ ๊ตฌ์ฑ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋์ด ์์ต๋๋ค. SQLite๋ ์๋๊ฐ ๋น ๋ฅด๋ฉฐ ํน์ํ ๊ตฌ์ฑ์ด ํ์ํ์ง ์์ผ๋ฉฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๋จ์ผ ํ์ผ๋ก ๋์คํฌ์ ์ ์ฅ๋๋ฏ๋ก ์ด๋ฌํ ์ํฉ์ ์ด์์ ์ ๋๋ค.
๊ทผ๊ฑฐ : ์ฒ์์๋ ๋ด๊ฐ๋ณด๊ณ ์๋ ์ฑ๋ฅ์ ์ค๋งํ์ต๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์ฑ ๋ฐฉ๋ฒ๊ณผ API ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ SQLite์ ์ฑ๋ฅ์ด ํฌ๊ฒ ๋ฌ๋ผ์ง ์ ์์ต๋๋ค (๋๋ ์ฝ์ ๋ฐ ์ ํ). ๋ชจ๋ ์ต์ ๊ณผ ๊ธฐ์ ์ด ๋ฌด์์ธ์ง ํ์ ํ๋ ๊ฒ์ ์ฌ์ํ ์ผ์ด ์๋๋ฏ๋ก ๋์ผํ ์ปค๋ฎค๋ํฐ์ ์กฐ์ฌ ๋ฌธ์ ๋ฅผ ๋ค๋ฅธ ์ฌ๋๋ค์ด ํด๊ฒฐํ๊ธฐ ์ํด ์คํ ์ค๋ฒํ๋ก ๋ฆฌ๋์ ๊ฒฐ๊ณผ๋ฅผ ๊ณต์ ํ๊ธฐ ์ํด์ด ์ปค๋ฎค๋ํฐ ์ํค ํญ๋ชฉ์ ์์ฑํ๋ ๊ฒ์ด ํ๋ช ํ๋ค๊ณ ์๊ฐํ์ต๋๋ค.
์คํ : ์ผ๋ฐ์ ์ธ ์๋ฏธ์ ์ฑ๋ฅ ํ (์ : โํธ๋์ญ์ ์ฌ์ฉโ )์ ๋ํด์๋ง ์ด์ผ๊ธฐํ๋ ๋์ C ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์ค์ ๋ก ๋ค์ํ ์ต์ ์ ์ํฅ์ ์ธก์ ํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค . ์ฐ๋ฆฌ๋ ๊ฐ๋จํ ๋ฐ์ดํฐ๋ก ์์ํ ๊ฒ์ ๋๋ค.
- ํ ๋ก ํ ์์ ์ ์ฒด ์ด์ก ์ผ์ ์ ๋ํ 28MB์ ํญ์ผ๋ก ๊ตฌ๋ถ ๋ ํ ์คํธ ํ์ผ (์ฝ 865,000 ๊ฐ์ ๋ ์ฝ๋)
- ๋ด ํ ์คํธ ์ปดํจํฐ๋ Windows XP๋ฅผ ์คํํ๋ 3.60GHz P4์ ๋๋ค.
- ์ด ์ฝ๋๋ Visual C ++ 2005์์ โ์์ ์ต์ ํโ(/ Ox) ๋ฐ Favor Fast Code (/ Ot)์ ํจ๊ป โ๋ฆด๋ฆฌ์คโ๋ก ์ปดํ์ผ๋ฉ๋๋ค .
- ํ ์คํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ง์ ์ปดํ์ผ ๋ SQLite โAmalgamationโ์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ๋ด๊ฐ ๊ฐ์ง๊ณ ์๋ SQLite ๋ฒ์ ์ ์กฐ๊ธ ์ค๋๋์์ง๋ง (3.6.7)์ด ๊ฒฐ๊ณผ๊ฐ ์ต์ ๋ฆด๋ฆฌ์ค์ ๋น์ทํ ๊ฒ์ผ๋ก ์๊ฐ๋ฉ๋๋ค (๊ทธ๋ ์ง ์์ผ๋ฉด ์๊ฒฌ์ ๋จ๊ฒจ์ฃผ์ธ์).
์ฝ๋๋ฅผ ์์ฑํ์!
์ฝ๋ : ํ ์คํธ ํ์ผ์ ํ ์ค์ฉ ์ฝ๊ณ ๋ฌธ์์ด์ ๊ฐ์ผ๋ก ๋ถํ ํ ๋ค์ SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ๋ ๊ฐ๋จํ C ํ๋ก๊ทธ๋จ์ ๋๋ค. ์ด โ๊ธฐ๋ณธโ๋ฒ์ ์ ์ฝ๋์์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์์ฑ๋์ง๋ง ์ค์ ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ์ง๋ ์์ต๋๋ค.
/*************************************************************
Baseline code to experiment with SQLite performance.
Input data is a 28 MB TAB-delimited text file of the
complete Toronto Transit System schedule/route info
from http://www.toronto.ca/open/datasets/ttc-routes/
**************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "sqlite3.h"
#define INPUTDATA "C:\\TTC_schedule_scheduleitem_10-27-2009.txt"
#define DATABASE "c:\\TTC_schedule_scheduleitem_10-27-2009.sqlite"
#define TABLE "CREATE TABLE IF NOT EXISTS TTC (id INTEGER PRIMARY KEY, Route_ID TEXT, Branch_Code TEXT, Version INTEGER, Stop INTEGER, Vehicle_Index INTEGER, Day Integer, Time TEXT)"
#define BUFFER_SIZE 256
int main(int argc, char **argv) {
sqlite3 * db;
sqlite3_stmt * stmt;
char * sErrMsg = 0;
char * tail = 0;
int nRetCode;
int n = 0;
clock_t cStartClock;
FILE * pFile;
char sInputBuf [BUFFER_SIZE] = "\0";
char * sRT = 0; /* Route */
char * sBR = 0; /* Branch */
char * sVR = 0; /* Version */
char * sST = 0; /* Stop Number */
char * sVI = 0; /* Vehicle */
char * sDT = 0; /* Date */
char * sTM = 0; /* Time */
char sSQL [BUFFER_SIZE] = "\0";
/*********************************************/
/* Open the Database and create the Schema */
sqlite3_open(DATABASE, &db);
sqlite3_exec(db, TABLE, NULL, NULL, &sErrMsg);
/*********************************************/
/* Open input file and import into Database*/
cStartClock = clock();
pFile = fopen (INPUTDATA,"r");
while (!feof(pFile)) {
fgets (sInputBuf, BUFFER_SIZE, pFile);
sRT = strtok (sInputBuf, "\t"); /* Get Route */
sBR = strtok (NULL, "\t"); /* Get Branch */
sVR = strtok (NULL, "\t"); /* Get Version */
sST = strtok (NULL, "\t"); /* Get Stop Number */
sVI = strtok (NULL, "\t"); /* Get Vehicle */
sDT = strtok (NULL, "\t"); /* Get Date */
sTM = strtok (NULL, "\t"); /* Get Time */
/* ACTUAL INSERT WILL GO HERE */
n++;
}
fclose (pFile);
printf("Imported %d records in %4.2f seconds\n", n, (clock() - cStartClock) / (double)CLOCKS_PER_SEC);
sqlite3_close(db);
return 0;
}
์ ์ดโ
์ฝ๋๋ฅผ์๋ ๊ทธ๋๋ก ์คํํ๋ฉด ์ค์ ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ด ์ํ๋์ง ์์ง๋ง ์์ C ํ์ผ I / O ๋ฐ ๋ฌธ์์ด ์ฒ๋ฆฌ ์์ ์ด ์ผ๋ง๋ ๋น ๋ฅธ์ง ์ ์ ์์ต๋๋ค.
0.94 ์ด ๋ด์ 864913 ๊ฐ์ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ ์์ต๋๋ค.
ํฐ! ์ค์ ๋ก ์ธ์ํธ๋ฅผ ์ํํ์ง ์์ผ๋ฉด ์ด๋น 920,000 ๊ฐ์ ์ธ์ํธ๋ฅผ ์ํ ํ ์ ์์ต๋๋ค.
โ๊ฐ์ฅ ์ต์ ์ ์๋๋ฆฌ์คโ
ํ์ผ์์ ์ฝ์ ๊ฐ์ ์ฌ์ฉํ์ฌ SQL ๋ฌธ์์ด์ ์์ฑํ๊ณ sqlite3_exec๋ฅผ ์ฌ์ฉํ์ฌ ํด๋น SQL ์์ ์ ํธ์ถํฉ๋๋ค.
sprintf(sSQL, "INSERT INTO TTC VALUES (NULL, '%s', '%s', '%s', '%s', '%s', '%s', '%s')", sRT, sBR, sVR, sST, sVI, sDT, sTM);
sqlite3_exec(db, sSQL, NULL, NULL, &sErrMsg);
SQL์ด ๋ชจ๋ ์ฝ์ ์ ๋ํด VDBE ์ฝ๋๋ก ์ปดํ์ผ๋๊ณ ๋ชจ๋ ์ฝ์ ์ด ์์ฒด ํธ๋์ญ์ ์์ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ์๋๊ฐ ๋๋ ค์ง๋๋ค. ์ผ๋ง๋ ๋๋ ค?
9933.61 ์ด ๋ด์ 864913 ๊ฐ์ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ ์์ต๋๋ค.
์ด์ผ! 2 ์๊ฐ 45 ๋ถ! ๊ทธ๊ฑด ๋จ์ง์ ์ด๋น 85 ์ฝ์ .
๊ฑฐ๋ ์ฌ์ฉ
๊ธฐ๋ณธ์ ์ผ๋ก SQLite๋ ๊ณ ์ ํ ํธ๋์ญ์ ๋ด์์ ๋ชจ๋ INSERT / UPDATE ๋ฌธ์ ํ๊ฐํฉ๋๋ค. ๋ง์ ์์ ์ธ์ํธ๋ฅผ ์ํํ๋ ๊ฒฝ์ฐ ์์ ์ ํธ๋์ญ์ ์ผ๋ก ๋ํํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &sErrMsg);
pFile = fopen (INPUTDATA,"r");
while (!feof(pFile)) {
...
}
fclose (pFile);
sqlite3_exec(db, "END TRANSACTION", NULL, NULL, &sErrMsg);
38.03 ์ด ๋ด์ 864913 ๊ฐ์ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ ์์ต๋๋ค.
๊ทธ๊ฒ ๋ซ๋ค. ํ ๋ฒ์ ํธ๋์ญ์ ์ผ๋ก ๋ชจ๋ ์ธ์ํธ๋ฅผ ํฌ์ฅํ๋ฉด ์ด๋น 23,000 ๊ฐ์ ์ธ์ํธ๋ก ์ฑ๋ฅ์ด ํฅ์๋์์ต๋๋ค .
์ค๋น๋ ์ง์ ์ฌ์ฉ
ํธ๋์ญ์
์ฌ์ฉ์ ํฌ๊ฒ ๊ฐ์ ๋์์ง๋ง ๋์ผํ SQL์ ๋ฐ๋ณตํด์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ชจ๋ ์ฝ์
์ ๋ํด SQL ๋ฌธ์ ๋ค์ ์ปดํ์ผํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์ต๋๋ค. ํ์์ ์ฌ์ฉ์ sqlite3_prepare_v2
๋ค์ ๋ฐ์ธ๋ ์ฌ์ฉํ์ฌ ๊ทธ ์ง์ ์ ๋ํ ์ฐ๋ฆฌ์ ๋งค๊ฐ ๋ณ์๋ฅผ ํ ๋ฒ ์ฐ๋ฆฌ์ SQL ๋ฌธ์ ์ปดํ์ผํฉ๋๋ค sqlite3_bind_text
:
/* Open input file and import into the database */
cStartClock = clock();
sprintf(sSQL, "INSERT INTO TTC VALUES (NULL, @RT, @BR, @VR, @ST, @VI, @DT, @TM)");
sqlite3_prepare_v2(db, sSQL, BUFFER_SIZE, &stmt, &tail);
sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &sErrMsg);
pFile = fopen (INPUTDATA,"r");
while (!feof(pFile)) {
fgets (sInputBuf, BUFFER_SIZE, pFile);
sRT = strtok (sInputBuf, "\t"); /* Get Route */
sBR = strtok (NULL, "\t"); /* Get Branch */
sVR = strtok (NULL, "\t"); /* Get Version */
sST = strtok (NULL, "\t"); /* Get Stop Number */
sVI = strtok (NULL, "\t"); /* Get Vehicle */
sDT = strtok (NULL, "\t"); /* Get Date */
sTM = strtok (NULL, "\t"); /* Get Time */
sqlite3_bind_text(stmt, 1, sRT, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, sBR, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 3, sVR, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 4, sST, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 5, sVI, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 6, sDT, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 7, sTM, -1, SQLITE_TRANSIENT);
sqlite3_step(stmt);
sqlite3_clear_bindings(stmt);
sqlite3_reset(stmt);
n++;
}
fclose (pFile);
sqlite3_exec(db, "END TRANSACTION", NULL, NULL, &sErrMsg);
printf("Imported %d records in %4.2f seconds\n", n, (clock() - cStartClock) / (double)CLOCKS_PER_SEC);
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
16.27 ์ด ๋ด์ 864913 ๊ฐ์ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ ์์ต๋๋ค.
์ข์! ์ด ์กฐ๊ธ ๋ ์ฝ๋ (์ ํํ๋ ๊ฒ์ ์์ง ๋ง์ธ์ ๋นํธ์ sqlite3_clear_bindings
๊ณผ sqlite3_reset
), ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ๋ ์ด์ ์ฐ๋ฆฌ์ ์ฑ๋ฅ์ ๋ ๋ฐฐ๋ก ์ด๋น 53,000 ์ฝ์
ํฉ๋๋ค.
PRAGMA ๋๊ธฐ์ = OFF
๊ธฐ๋ณธ์ ์ผ๋ก SQLite๋ OS ์์ค ์ฐ๊ธฐ ๋ช
๋ น์ ์คํ ํ ํ ์ผ์ ์ค์ง๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ฐ์ดํฐ๊ฐ ๋์คํฌ์ ๊ธฐ๋ก๋ฉ๋๋ค. ์ ์ค์ synchronous = OFF
ํ์ฌ SQLite์ ๋ฐ์ดํฐ๋ฅผ OS๋ก ์ ๋ฌํ์ฌ ์ฐ๊ธฐ๋ฅผ ๊ณ์ํ๋๋ก ์ง์ํฉ๋๋ค. ๋ฐ์ดํฐ๊ฐ ํ๋ํฐ์ ๊ธฐ๋ก๋๊ธฐ ์ ์ ์ปดํจํฐ์ ์น๋ช
์ ์ธ ์ถฉ๋ (๋๋ ์ ์ )์ด ๋ฐ์ํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ผ์ด ์์ ๋ ์ ์์ต๋๋ค.
/* Open the database and create the schema */
sqlite3_open(DATABASE, &db);
sqlite3_exec(db, TABLE, NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA synchronous = OFF", NULL, NULL, &sErrMsg);
12.41 ์ด ๋ด์ 864913 ๊ฐ์ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ ์์ต๋๋ค.
ํฅ์๋ ๊ธฐ๋ฅ์ ์ด์ ๋ ์์ง๋ง ์ด๋น ์ต๋ 69,600 ๊ฐ์ ์ฝ์ ๋ฌผ์ด ์์ต๋๋ค.
PRAGMA journal_mode = ๋ฉ๋ชจ๋ฆฌ
ํ๊ฐํ์ฌ ๋กค๋ฐฑ ์ ๋์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ์ญ์์ค PRAGMA journal_mode = MEMORY
. ํธ๋์ญ์
์ด ๋นจ๋ผ์ง์ง๋ง ํธ๋์ญ์
๋์ค ์ ์์ด ๋๊ธฐ๊ฑฐ๋ ํ๋ก๊ทธ๋จ์ด ์ถฉ๋ํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๋ถ๋ถ์ ์ผ๋ก ์๋ฃ๋ ํธ๋์ญ์
์ผ๋ก ์ธํด ์์๋ ์ํ๋ก ๋จ์์์ ์ ์์ต๋๋ค.
/* Open the database and create the schema */
sqlite3_open(DATABASE, &db);
sqlite3_exec(db, TABLE, NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA journal_mode = MEMORY", NULL, NULL, &sErrMsg);
13.50 ์ด ๋ด์ 864913 ๊ฐ์ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ ์์ต๋๋ค.
์ด๋น 64,000 ๊ฐ์ ์ธ์ํธ ์์ ์ด์ ์ต์ ํ๋ณด๋ค ์ฝ๊ฐ ๋๋ฆฝ๋๋ค .
PRAGMA ๋๊ธฐ = OFF ๋ฐ PRAGMA journal_mode = MEMORY
์ด์ ๋ ๊ฐ์ง ์ต์ ํ๋ฅผ ๊ฒฐํฉ ํด ๋ด ์๋ค. ์ข ๋ ์ํํ์ง๋ง (์ถฉ๋์ ๊ฒฝ์ฐ) ์ํ์ ์ด์ํ์ง ์๊ณ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
/* Open the database and create the schema */
sqlite3_open(DATABASE, &db);
sqlite3_exec(db, TABLE, NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA synchronous = OFF", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "PRAGMA journal_mode = MEMORY", NULL, NULL, &sErrMsg);
12.00 ์ด ๋ด์ 864913 ๊ฐ์ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ ์์ต๋๋ค.
ํ์์ ์ธ! ์ด๋น 72,000 ๊ฐ์ ์ธ์ํธ ๋ฅผ ์ํ ํ ์ ์์ต๋๋ค.
์ธ ๋ฉ๋ชจ๋ฆฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ
ํฅ์ ์ํด ์ด์ ์ ๋ชจ๋ ์ต์ ํ๋ฅผ ๊ธฐ๋ฐ์ผ๋กํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ผ ์ด๋ฆ์ ์ฌ์ ์ํ์ฌ RAM์์ ์์ ํ ์์ ํ๋๋กํ๊ฒ ์ต๋๋ค.
#define DATABASE ":memory:"
10.94 ์ด ๋ด์ 864913 ๊ฐ์ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ ์์ต๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ RAM์ ์ ์ฅํ๋ ๊ฒ์ ์ค์ฉ์ ์ด์ง๋ ์์ง๋ง ์ด๋น 79,000 ๊ฐ์ ์ฝ์ ์ ์ํ ํ ์ ์๋ค๋ ์ ์ด ์ธ์์ ์ ๋๋ค .
C ์ฝ๋ ๋ฆฌํฉํ ๋ง
ํน๋ณํ SQLite ๊ฐ์ ์ ์๋์ง๋ง ๋ฃจํ char*
์์ ์ถ๊ฐ ํ ๋น ์์
์ ์ข์ํ์ง ์์ต๋๋ค while
. ํด๋น ์ฝ๋๋ฅผ ์ ์ํ๊ฒ ๋ฆฌํฉํฐ๋งํ์ฌ ์ถ๋ ฅ์ strtok()
์ง์ ๋ก ์ ๋ฌ sqlite3_bind_text()
ํ๊ณ ์ปดํ์ผ๋ฌ๊ฐ ์๋๋ฅผ ๋์ด๋๋กํ๊ฒ ์ต๋๋ค.
pFile = fopen (INPUTDATA,"r");
while (!feof(pFile)) {
fgets (sInputBuf, BUFFER_SIZE, pFile);
sqlite3_bind_text(stmt, 1, strtok (sInputBuf, "\t"), -1, SQLITE_TRANSIENT); /* Get Route */
sqlite3_bind_text(stmt, 2, strtok (NULL, "\t"), -1, SQLITE_TRANSIENT); /* Get Branch */
sqlite3_bind_text(stmt, 3, strtok (NULL, "\t"), -1, SQLITE_TRANSIENT); /* Get Version */
sqlite3_bind_text(stmt, 4, strtok (NULL, "\t"), -1, SQLITE_TRANSIENT); /* Get Stop Number */
sqlite3_bind_text(stmt, 5, strtok (NULL, "\t"), -1, SQLITE_TRANSIENT); /* Get Vehicle */
sqlite3_bind_text(stmt, 6, strtok (NULL, "\t"), -1, SQLITE_TRANSIENT); /* Get Date */
sqlite3_bind_text(stmt, 7, strtok (NULL, "\t"), -1, SQLITE_TRANSIENT); /* Get Time */
sqlite3_step(stmt); /* Execute the SQL Statement */
sqlite3_clear_bindings(stmt); /* Clear bindings */
sqlite3_reset(stmt); /* Reset VDBE */
n++;
}
fclose (pFile);
์ฐธ๊ณ : ์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ผ์ ๋ค์ ์ฌ์ฉํฉ๋๋ค. ์ธ ๋ฉ๋ชจ๋ฆฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋น ๋ฅด์ง ๋ง ๋ฐ๋์ ์ค์ฉ์ ์ด์ง๋ ์์ต๋๋ค.
8.94 ์ด ๋ด์ 864913 ๊ฐ์ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ ์์ต๋๋ค.
๋งค๊ฐ ๋ณ์ ๋ฐ์ธ๋ฉ์ ์ฌ์ฉ ๋ ๋ฌธ์์ด ์ฒ๋ฆฌ ์ฝ๋๋ฅผ ์ฝ๊ฐ ๋ฆฌํฉํ ๋งํ๋ฉด ์ด๋น 96,700 ๊ฐ์ ์ฝ์ ์ ์ํ ํ ์์์์ต๋๋ค . ๋๋ ์ด๊ฒ์ด ๋งค์ฐ ๋น ๋ฅด๋ค๊ณ ๋งํ๋ ๊ฒ์ด ์์ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค . ๋ค๋ฅธ ๋ณ์ (์ : ํ์ด์ง ํฌ๊ธฐ, ์์ธ ์์ฑ ๋ฑ)๋ฅผ ์กฐ์ ํ๊ธฐ ์์ํ๋ฉด ์ด๊ฒ์ด ๋ฒค์น ๋งํฌ๊ฐ๋ฉ๋๋ค.
์์ฝ (์ง๊ธ๊น์ง)
๋๋ ๋น์ ์ด ์ฌ์ ํ ๋์ ํจ๊ป ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค! ์ด ๊ธธ์ ์์ํ ์ด์ ๋ ๋๋ ์ฝ์ ์ฑ๋ฅ์ด SQLite์ ๋ฐ๋ผ ํฌ๊ฒ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์ด์ ์๋๋ฅผ ๋์ด๊ธฐ ์ํด ์ด๋ค ๋ณ๊ฒฝ์ด ํ์ํ์ง ํญ์ ๋ช ํํ์ง๋ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋์ผํ ์ปดํ์ผ๋ฌ (๋ฐ ์ปดํ์ผ๋ฌ ์ต์ ), ๋์ผํ ๋ฒ์ ์ SQLite ๋ฐ ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ๋์ SQLite ์ฌ์ฉ์ ์ต์ ํํ์ฌ ์ด๋น 85 ์ฝ์ ์ ์ต์ ์ ์๋๋ฆฌ์ค์์ ์ด๋น 96,000 ์ด์์ ์ฝ์ ์ผ๋ก ์ ํํฉ๋๋ค!
INDEX ์์ฑ ํ INSERT vs. INSERT ์์ฑ ํ INDEX ์์ฑ
SELECT
์ฑ๋ฅ ์ธก์ ์ ์์ํ๊ธฐ ์ ์ ์ธ๋ฑ์ค๋ฅผ ๋ง๋ค ๊ฒ์์ ์๊ณ ์์ต๋๋ค. ์๋ ๋ต๋ณ ์ค ํ๋์์ ๋๋ ์ฝ์
์ ์ํ ํ ๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ์
ํ ํ ์์ธ์ ๋ง๋๋ ๊ฒ์ด ๋ ๋น ๋ฆ
๋๋ค (๋จผ์ ์์ธ์ ๋ง๋ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์
ํ๋ ๊ฒ๊ณผ๋ ๋์กฐ์ ์ผ๋ก). ํด๋ณด์:
์ธ๋ฑ์ค ์์ฑ ํ ๋ฐ์ดํฐ ์ฝ์
sqlite3_exec(db, "CREATE INDEX 'TTC_Stop_Index' ON 'TTC' ('Stop')", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &sErrMsg);
...
18.13 ์ด ๋ด์ 864913 ๊ฐ์ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ ์์ต๋๋ค.
๋ฐ์ดํฐ ์ฝ์ ํ ์ธ๋ฑ์ค ์์ฑ
...
sqlite3_exec(db, "END TRANSACTION", NULL, NULL, &sErrMsg);
sqlite3_exec(db, "CREATE INDEX 'TTC_Stop_Index' ON 'TTC' ('Stop')", NULL, NULL, &sErrMsg);
13.66 ์ด ์์ 864913 ๊ฐ์ ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ ์์ต๋๋ค.
์์๋๋ก, ํ๋์ ์ด์ด ์์ธํ๋๋ฉด ๋๋ ์ฝ์ ์ด ๋๋ ค์ง์ง๋ง ๋ฐ์ดํฐ๊ฐ ์ฝ์ ๋ ํ ์์ธ์ด ์์ฑ๋๋ฉด ์ฐจ์ด๊ฐ ๋ฐ์ํฉ๋๋ค. ์ธ๋ฑ์ค๊ฐ์๋ ๊ธฐ์ค์ ์ด๋น 96,000 ๊ฐ์ ์ธ์ํธ์ ๋๋ค. ๋จผ์ ์ธ๋ฑ์ค๋ฅผ ์์ฑ ํ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ๋ฉด ์ด๋น 47,700 ๊ฐ์ ์ฝ์ ์ด ์์ฑ๋๋ ๋ฐ๋ฉด, ๋ฐ์ดํฐ๋ฅผ ๋จผ์ ์ฝ์ ํ ๋ค์ ์ธ๋ฑ์ค๋ฅผ ์์ฑํ๋ฉด ์ด๋น 63,300 ๊ฐ์ ์ฝ์ ์ด ์์ฑ๋ฉ๋๋ค.
๋ค๋ฅธ ์๋๋ฆฌ์ค์ ๋ํ ์ ์์ ๊ธฐ์๊ฒ ์๊ฐํฉ๋๋ค โฆ ๊ณง SELECT ์ฟผ๋ฆฌ์ ๋ํ ์ ์ฌํ ๋ฐ์ดํฐ๋ฅผ ์ปดํ์ผ ํ ๊ฒ์ ๋๋ค.
๋ต๋ณ
๋ช ๊ฐ์ง ํ :
- ํธ๋์ญ์ ์ ์ฝ์ / ์ ๋ฐ์ดํธ๋ฅผ ๋ฃ์ต๋๋ค.
- ์ด์ ๋ฒ์ ์ SQLite์ ๊ฒฝ์ฐ ๋ ํธ์ง์ฆ์ ์ธ ์ ๋ ๋ชจ๋ (
pragma journal_mode
)๋ฅผ ๊ณ ๋ คํ์ญ์์ค . ์ดNORMAL
๋ค์์ดOFF
๋๋ฌด OS๊ฐ ์ถฉ๋ํ๋ ๊ฒฝ์ฐ ๊ฐ๋ฅ์ฑ์ด ์์์ง๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํด ๊ฑฑ์ ํ์ง ์๋ ๊ฒฝ์ฐ ํฌ๊ฒ ์๋ ์ฝ์ ๋์ผ ์์๋ค. ์์ฉ ํ๋ก๊ทธ๋จ์ด ์ถฉ๋ํ๋ฉด ๋ฐ์ดํฐ๊ฐ ์ ์์ด์ด์ผํฉ๋๋ค. ์ต์ ๋ฒ์ ์์๋OFF/MEMORY
์ค์ ์ด ์์ฉ ํ๋ก๊ทธ๋จ ์์ค ์ถฉ๋์ ์์ ํ์ง ์์ต๋๋ค. - ํ์ด์ง ํฌ๊ธฐ๋ก ์ฌ์ํ๋ฉด ์ฐจ์ด๊ฐ ์์ต๋๋ค (
PRAGMA page_size
). ๋ ํฐ ํ์ด์ง ํฌ๊ธฐ๋ฅผ ๊ฐ์ง๋ฉด ๋ ํฐ ํ์ด์ง๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ง๋๋ฏ๋ก ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ ์๋๊ฐ ์ฝ๊ฐ ๋นจ๋ผ์ง๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ฌ์ฉ๋ฉ๋๋ค. - ์์ธ์ด์๋ ๊ฒฝ์ฐ
CREATE INDEX
๋ชจ๋ ์ฝ์ ์์ ์ ์ํ ํ ํ ์ ํ ๋ฅผ ๊ณ ๋ ค ํ์ญ์์ค. ์ด๊ฒ์ ์์ธ์ ์์ฑํ๊ณ ์ฝ์ ์ ์ํํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋น ๋ฆ ๋๋ค. - ์ฐ๊ธฐ๊ฐ ์๋ฃ ๋ ๋ ์ ์ฒด ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ ๊ธฐ๊ณ ์ฌ๋ฌ ํ๋ ๊ธฐ๊ฐ ๊ฐ๋ฅํ๋๋ผ๋ ์ฐ๊ธฐ๊ฐ ์ ๊ธฐ๋ฏ๋ก SQLite์ ๋์์ ์ก์ธ์ค ํ ์์๋ ๊ฒฝ์ฐ ๋งค์ฐ์ฃผ์ํด์ผํฉ๋๋ค. ์ต์ SQLite ๋ฒ์ ์ WAL์ด ์ถ๊ฐ๋์ด ๋ค์ ๊ฐ์ ๋์์ต๋๋ค.
- ๊ณต๊ฐ์ ์ ์ฝํ์ญ์์ค. ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ ๋น ๋ฆ
๋๋ค. ์๋ฅผ ๋ค์ด, ํค ๊ฐ ์์ด์๋
INTEGER PRIMARY KEY
๊ฒฝ์ฐ ํค๋ฅผ ๊ฐ๋ฅ ํ๋ฉด ํค๋ก ๋ง๋ค์ด ํ ์ด๋ธ์ ๋ด์ฌ ๋ ๊ณ ์ ํ ๋ฒํธ ์ด์ ๋์ฒดํ์ญ์์ค. - ์ฌ๋ฌ ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๊ณต์ ํ์ด์ง ์บ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ก๋ ๋ ํ์ด์ง๋ฅผ ์ค๋ ๋๊ฐ์ ๊ณต์ ํ ์ ์์ผ๋ฏ๋ก ๊ฐ ๋น์ผ I / O ํธ์ถ์ ํผํ ์ ์์ต๋๋ค.
- ์ฌ์ฉํ์ง ๋ง์ญ์์ค
!feof(file)
!
๋๋ ๋ํ ์ฌ๊ธฐ ์ ์ฌ๊ธฐ์ ๋น์ทํ ์ง๋ฌธ ์ ํ๋ค .
๋ต๋ณ
ํด๋น ์ธ์ํธ SQLITE_STATIC
๋์ ์ฌ์ฉํ์ญ์์ค SQLITE_TRANSIENT
.
SQLITE_TRANSIENT
๋ฐํํ๊ธฐ ์ ์ SQLite๊ฐ ๋ฌธ์์ด ๋ฐ์ดํฐ๋ฅผ ๋ณต์ฌํ๊ฒํฉ๋๋ค.
SQLITE_STATIC
์ฃผ์ด์ง ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ ์ฟผ๋ฆฌ๊ฐ ์ํ ๋ ๋๊น์ง ์ ํจํฉ๋๋ค (์ด ๋ฃจํ์์๋ ํญ์ ๊ทธ๋ ์ต๋๋ค). ์ด๋ฅผ ํตํด ๋ฃจํ ๋น ์ฌ๋ฌ ํ ๋น, ๋ณต์ฌ ๋ฐ ํ ๋น ํด์ ์์
์ ์ค์ผ ์ ์์ต๋๋ค. ์๋ง ํฐ ๊ฐ์ .
๋ต๋ณ
ํผํ์ญ์์ค sqlite3_clear_bindings(stmt)
.
ํ ์คํธ์ ์ฝ๋๋ ๋ฐ์ธ๋ฉ์ด ์ถฉ๋ถํ ๋๋ง๋ค ๋ฐ์ธ๋ฉ์ ์ค์ ํฉ๋๋ค.
SQLite ๋ฌธ์ ์ C API ์๊ฐ ๋ ๋ค์๊ณผ ๊ฐ์ด ๋งํฉ๋๋ค.
sqlite3_step () ์ ์ฒ์์ผ๋ก ํธ์ถํ๊ธฐ ์ ์ ๋๋ sqlite3_reset () ์งํ ์ ์์ฉ ํ๋ก๊ทธ๋จ์ sqlite3_bind () ์ธํฐํ์ด์ค๋ฅผ ํธ์ถํ์ฌ ๊ฐ์ ๋งค๊ฐ ๋ณ์์ ์ฒจ๋ถ ํ ์ ์์ต๋๋ค
. sqlite3_bind () ์ ๋ํ ๊ฐ ํธ์ถ ์ ๋์ผํ ๋งค๊ฐ ๋ณ์์ ์ด์ ๋ฐ์ธ๋ฉ์ ๋์ฒดํฉ๋๋ค.
sqlite3_clear_bindings
๋จ์ํ ๋ฐ์ธ๋ฉ์ ์ค์ ํ๋ ๊ฒ ์ธ์๋ ํธ์ถํด์ผํ๋ค๊ณ ๋งํ๋ ๋ฌธ์์๋ ์๋ฌด๊ฒ๋ ์์ต๋๋ค .
์์ธํ ๋ด์ฉ : avoid_sqlite3_clear_bindings ()
๋ต๋ณ
๋ฒํฌ ์ธ์ํธ
์ด ๊ฒ์๋ฌผ๊ณผ ์คํ ์ค๋ฒํ๋ก ์ง๋ฌธ์์ ์๊ฐ์ ์ป์์ต๋๋ค .SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ๋ฒ์ ์ฌ๋ฌ ํ์ ์ฝ์ ํ ์ ์์ต๋๊น? -์ฒซ Git ์ ์ฅ์๋ฅผ ๊ฒ์ํ์ต๋๋ค .
https://github.com/rdpoor/CreateOrUpdate
์ด๋ ActiveRecord ๋ฐฐ์ด์ MySQL , SQLite ๋๋ PostgreSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋๋๋ก๋ ํฉ๋๋ค. ๊ธฐ์กด ๋ ์ฝ๋๋ฅผ ๋ฌด์ํ๊ฑฐ๋ ๋ฎ์ด ์ฐ๊ฑฐ๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๋ ์ต์ ์ด ํฌํจ๋์ด ์์ต๋๋ค. ํ์์ ๊ธฐ์ด ๋ฒค์น ๋งํฌ๋ ์์ฐจ์ ์ฐ๊ธฐ (YMMV)์ ๋นํด ์๋๊ฐ 10 ๋ฐฐ ํฅ์๋์์ต๋๋ค.
๋์ฉ๋ ๋ฐ์ดํฐ ์ธํธ๋ฅผ ์์ฃผ ๊ฐ์ ธ์์ผํ๋ ํ๋ก๋์ ์ฝ๋์์ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ๋งค์ฐ ๋ง์กฑํฉ๋๋ค.
๋ต๋ณ
INSERT / UPDATE ๋ฌธ์ ์ฒญํฌ ํ ์ ์์ผ๋ฉด ๋๋ ๊ฐ์ ธ ์ค๊ธฐ๊ฐ ๊ฐ์ฅ ์ ์ํ๋๋ ๊ฒ ๊ฐ์ต๋๋ค . 10,000 ๊ฐ ์ ๋์ ๊ฐ์ YMMV โฆ ๋ช ํ๋ง์๋ ํ ์ด๋ธ์์ ์ ์๋ํ์ต๋๋ค.
๋ต๋ณ
์ฝ๊ธฐ์๋ง ๊ด์ฌ์ด์๋ ๊ฒฝ์ฐ ๋ค์ ๋น ๋ฅธ (๊ทธ๋ฌ๋ ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ์ ์์) ๋ฒ์ ์ ์ฌ๋ฌ ์ค๋ ๋ (์ค๋ ๋ ๋น ์ฐ๊ฒฐ)์ ์ฌ๋ฌ ์ฐ๊ฒฐ์์ ์ฝ๋ ๊ฒ์ ๋๋ค.
๋จผ์ ํ์์ ํญ๋ชฉ์ ์ฐพ์ผ์ญ์์ค.
SELECT COUNT(*) FROM table
๊ทธ๋ฐ ๋ค์ ํ์ด์ง๋ฅผ ์ฝ์ต๋๋ค (LIMIT / OFFSET).
SELECT * FROM table ORDER BY _ROWID_ LIMIT <limit> OFFSET <offset>
๋ค์๊ณผ ๊ฐ์ด ์ค๋ ๋ ๋น ๊ณ์ฐ๋๋ ์์น๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
int limit = (count + n_threads - 1)/n_threads;
๊ฐ ์ค๋ ๋๋ง๋ค :
int offset = thread_index * limit
์ฐ๋ฆฌ์ ์์ (200mb) db์ ๊ฒฝ์ฐ 50-75 %์ ์๋๊ฐ ํฅ์๋์์ต๋๋ค (Windows 7์ ๊ฒฝ์ฐ 3.8.0.2 64 ๋นํธ). ์ฐ๋ฆฌ ํ ์ด๋ธ์ ์ ๊ทํ๋์ง ์์์ต๋๋ค (1000-1500 ์ด, ์ฝ 100,000 ๊ฐ ์ด์์ ํ).
์ค๋ ๋๊ฐ ๋๋ฌด ๋ง๊ฑฐ๋ ๋๋ฌด ์ ์ผ๋ฉด ๋ฒค์น๋งํนํ๊ณ ํ๋กํ์ ์์ฑํด์ผํฉ๋๋ค.
๋ํ ์ฐ๋ฆฌ๋ฅผ ์ํด SHAREDCACHE๋ ์ฑ๋ฅ์ ๋๋ฆฌ๊ฒ ๋ง๋ค์์ผ๋ฏ๋ก PRIVATECACHE๋ฅผ ์๋์ผ๋ก ๋ฃ์์ต๋๋ค.
๋ต๋ณ
cache_size๋ฅผ ๋ ๋์ ๊ฐ์ผ๋ก ์ฌ๋ฆด ๋๊น์ง ํธ๋์ญ์
์์ ์ด์ต์ ์ป์ง ๋ชปํ์ต๋๋ค. PRAGMA cache_size=10000;