2012-11-15 2 views
5

나는 임베디드 리눅스에서 실행되는 응용 프로그램을 가지고 있습니다. 각 행에 수천 개의 행과 52 개의 열이있는 테이블이있는 사전 구축 된 DB가 있습니다. 실행 시간에 'INSERT'를 수행하면 디스크 조각화가 생기므로 대신 DB 쓰레기를 많이 넣고 'INSERT'를 실행하고 런타임에는 DB를 작성해야한다는 점을 염두에두고 DB를 작성했습니다 나는 'UPDATE'를 사용한다.SQLite WAL 성능 향상

DB에 3 초마다 많은 데이터를 쓰고 있으며 쓰기 절차가 빠르기 때문에 SQLite에서 WAL 모드를 사용합니다. 나는 성능에 문제가있다. 체크 포인트가 발생할 때마다 너무 오래 걸리고 프로세서는 3 초 이내에 처리 할 수없는 것으로 보입니다. 이를 개선하기 위해 필자는 10 번의 쓰기 호출 후에 주 스레드에서 메시지 큐를 받고 검사 점보다 큰 스레드를 만들었습니다.

이제는 상황이 더 좋아 보이지만 WAL 파일이 점점 더 커지고있는 것 같습니다. 여기서 어떻게 해결할 수 있습니까?

답변

5

조각화를 방지하고 데이터를 미리 삽입해야하는 필요성을 제거하려면 sqlite3_file_control()SQLITE_FCNTL_CHUNK_SIZE을 사용하여 청크 크기를 설정해야합니다. 데이터베이스 파일 공간을 큰 덩어리 (한 번에 1MB)로 할당하면 파일 시스템 조각화가 줄어들고 성능이 향상됩니다. Mozilla 프로젝트는 currently using this setting이고, Firefox/Thunderbird는 great success입니다.

WAL 관련. 많은 양의 데이터를 자주 작성하는 경우 쓰기를 더 큰 트랜잭션으로 래핑하는 것을 고려해야합니다. 일반적으로 모든 INSERT는 자동으로 커밋되며 SQLite는 데이터가 실제로 디스크 나 플래시로 플러시 될 때까지 기다려야합니다. 이는 분명히 매우 느립니다. 하나의 트랜잭션에 여러 개의 쓰기를 래핑하는 경우 SQLite는 모든 단일 행에 대해 걱정할 필요가 없으며 한 번에 많은 행을 플러시 할 수 있으며 단일 플래시 쓰기가 가능하므로 훨씬 빠릅니다. 그렇다면 가능한 한 수백 건의 쓰기를 하나의 트랜잭션으로 래핑하십시오.

내 경험으로 볼 때 플래시의 WAL은 실제로 잘 작동하지 않으며 오래된 저널링 모드를 유지하는 것이 더 유리하다는 것을 알았습니다. 예를 들어, Android 4는 SQLite 데이터베이스에 WAL 모드를 사용하지 않으며 이유가있을 수 있습니다. WAL은 일부 상황에서는 제약없이 성장할 수있는 경향이 있음을 알고 있습니다 (단, 거래가 거의 이루어지지 않을 경우에도 발생하므로 꼭 한 번 수행하십시오).

+1

이것은 데이터베이스 파일의 파일 공간 할당에 영향을줍니다. 내가 WAL 파일에 할당하는 것이 청크 크기를 존중하지 않는다는 것을 이해합니다. –

1

WAL 모드에서 SQLite는 변경된 모든 페이지를 -wal 파일에 씁니다. 체크 포인트 중에 만 이러한 페이지가 다시 데이터베이스 파일에 기록됩니다.

-wal 파일은 동시 판독기가없는 경우에만 잘릴 수 있습니다.

SQLITE_CHECKPOINT_RESTART으로 호출하거나 PRAGMA wal_checkpoint(RESTART)을 실행하여 WAL 파일을 명시 적으로 지울 수는 있지만, 동시 판독기가있는 경우에는 실패합니다.

+0

내 질문에 대답하지 않는 것 같습니다. –