2009-04-25 5 views
12

테이블과 기본 키가 두 개의 정수로 구성된 Sqlite3 데이터베이스가 있는데 많은 데이터를 삽입하려고합니다 (예 : 약 1GB 정도)Sqlite3 : 삽입하는 동안 기본 키 색인을 사용하지 않도록 설정 하시겠습니까?

내가 겪고있는 문제는 다음과 같습니다. 기본 키를 만드는 것 또한 암묵적으로 인덱스를 만듭니다. 내 경우에는 커밋을 한 후 크롤링을 중단합니다. (데이터베이스 파일이 NFS에 있기 때문에 발생합니다. sigh).

그래서 임시로 해당 색인을 비활성화하고 싶습니다. 지금까지 필자의 가장 좋은 계획은 기본 키의 자동 인덱스를 삭제하는 것이었지만, SQLite는이를 좋아하지 않으므로 시도 할 때 오류가 발생합니다.

두 번째로 좋은 계획은 응용 프로그램이 네트워크 드라이브에 데이터베이스의 투명한 복사본을 만들어 수정 한 다음 다시 병합하는 것입니다. 대부분의 SQlite/NFS 질문과 달리 액세스 동시성은 필요하지 않습니다.

그런 식으로 올바른 방법은 무엇입니까?

업데이트 : 그러나 모든 다음, 일괄 항목을 삽입하는 사실에있어 :

PRAGMA synchronous = OFF 
PRAGMA journal_mode = OFF 
PRAGMA locking_mode = EXCLUSIVE 
PRAGMA temp_store = MEMORY 

UPDATE 2 :

내가 이미 사용하고 플래그를 지정하는 것을 잊었다 일괄 처리는 이전보다 커밋 속도가 느리다 (나는 이것이 인덱스의 크기와 관련이 있다고 가정한다). 나는 10k와 50k 튜플 사이의 일괄 처리를 시도했다. 각 튜플은 두 개의 정수와 부동 소수점이다.

답변

10
  1. 삽입 된 인덱스는 행의 유일한 주소이기 때문에 삭제할 수 없습니다.
  2. 두 개의 정수 키를 단일 긴 키 = (key1 < < 32) + key2에 병합하십시오. 데이터에서 주요
  3. 채우기를 제외하고 추가 인덱스를 제거 (만 1 개 인덱스가됩니다 경우에) 적어도 4096
  4. 새로운 DB에 대한
  5. 설정 페이지 크기 youd가 스키마의 INTEGER 기본 키로이을 기본 키가 커지도록 SORTED 순서.
  6. 재사용 명령, 문자열에서 각 시간을 생성하지 않는
  7. 당신이 남아있는만큼 메모리에
  8. 설정 페이지 캐시 크기
  9. (즉, 캐시 크기를 기억 바이트 수를 페이지 수에 있지만) 50000 개 항목을 커밋하십시오.추가 인덱스가있는 경우
  10. - 후에 만 ​​ALL을 만들 데이터 테이블

당신이 (sqlite가가 64 비트를 사용하는 동안, 당신은 32 비트를 사용하고있는 생각, 그래서 가능 키를 병합 할 수 있습니다 경우에) 및 정렬 된 순서로 데이터를 채우기 나는 당신이 두 번째와 동일한 성능으로 첫 번째 Gb를 채울 것이고 둘 다 충분히 빠를 것이라고 확신합니다.

+0

하나의 데이터 당 금액 유지 INSERT cache_size 매개 변수로 확인 된 문이이 트릭을 수행하는 것으로 보입니다. 분명히 캐시가 많기 때문에 한 번에 더 많은 항목을 삽입 할 수 있습니다. 또한 결국 모든 것을 끝내고 커밋을 할 수있는 것처럼 보입니다. –

+0

글쎄, 할 수있어. 하지만 O (1) 인 삽입 작업의 주된 트릭은 해당 인덱스로 정렬 된 데이터를 채우는 것이지만 데이터가 메모리 캐시에 들어갈 경우 모든 것이 실제로 빠릅니다. 커밋 크기를 캐시 크기보다 작게 유지하는 것이 합당합니다. 그렇지 않으면 sqlite가 강제로 디스크로 옮깁니다. – Mash

6

각 신규 거래가 INSERT 개인 거래로 수행하고 있습니까?

BEGIN TRANSACTIONINSERT 행을 일괄 적으로 사용하는 경우 인덱스는 각 트랜잭션이 끝날 때만 재구성됩니다.

+0

것입니다. 나는 그걸 너무 막 제안하려고했다. :) –

+0

네, 그렇지만 전체 기가 바이트를 하나의 트랜잭션으로 짜 넣을 수 있습니까? 나는 그 사고와 관련이 있는지 잘 모르겠지만 거의 모든 사고에 의해 (커밋 진술서를 넣는 것을 잊어 버렸습니다.) 그리고 디스크 입출력 오류가 절반 정도 발생했습니다 ... –