2013-07-24 4 views
1

데이터로드가 CSV 형식입니다. 단일 텍스트 필드 (기본 키)를 기반으로이 데이터를 인덱싱 할 수 있어야하므로 데이터베이스에 입력 할 생각입니다. 이전 프로젝트의 sqlite에 익숙하므로 해당 엔진을 사용하기로 결정했습니다.SQLite 데이터베이스에 수억 개의 행을 삽입하는 가장 좋은 방법은 무엇입니까?

몇 가지 실험이 끝난 후 1 억 개의 레코드를 하나의 테이블에 저장하는 것이 잘 작동하지 않는다는 것을 깨달았습니다. 인덱싱 단계가 꽤 빨리 크롤링 속도가 느려집니다. 나는이 문제에 대한 두 가지 해결책을 마련 할 수 : 나는 두 번째 솔루션으로 가서 여러 데이터베이스

에 여러 테이블

  • 파티션의 데이터에

    1. 파티션의 데이터를 (이것은 몇 가지 큰 파일을 얻을 수 하나의 큰 파일 대신). 내 파티션 방법은 기본 키의 처음 두 문자를 보는 것입니다. 각 파티션에는 약 2 백만 개의 레코드가 있으며 약 50 개의 파티션이 있습니다.

      저는 파이썬에서 sqlite3 모듈을 사용하고 있습니다. 프로세스의 전체 기간 동안 50 개의 데이터베이스 연결과 열린 커서를 유지합니다. 각 행에 대해 기본 키의 처음 두 문자를보고 사전 조회를 통해 오른쪽 커서를 가져오고 커서에서 execute를 호출하여 단일 삽입 문을 수행합니다.

      불행히도, 삽입 속도는 잠시 후 참을성없는 수준으로 감소합니다 (처리 된 레코드는 약 1,000 만 건입니다). 이 문제를 해결하려면 어떻게해야합니까? 제가하고있는 일을하는 더 좋은 방법이 있습니까?

  • +0

    데이터를 업데이트하거나 검색 만해야합니까? 큰 변수가 포함 된 핵심 가변 크기입니까? 콘텐츠의 크기가 다양합니까 (큰 유사 콘텐츠)? – 6502

    +0

    방금 ​​검색해야합니다. 데이터는 읽기 전용입니다. 키와 내용은 가변적이지만 차이는 크지 않습니다. 내용은 가변적이며 큰 차이가 있습니다. – misha

    +0

    이 답변을 확인해 주셔서 감사합니다. https://stackoverflow.com/questions/48174355/laravel-insert-millions-of-database-rows-from-models/48176164#48176164 – Ryanthehouse

    답변

    1

    난 당신이 가진 문제는 프로세싱이 단지 메모리 버퍼를 사용할 수 없다는 것입니다. 하드 디스크 헤드가 50 개 위치 사이에서 무작위로 점프하고 있습니다. 이것이 개가 느립니다. 당신이 시도 할 수

    뭔가 그냥 한 번에 하나 개의 부분 집합을 처리 :

    seen = {} # Key prefixes already processed 
    while True: 
        k0 = None # Current prefix 
        for L in all_the_data: 
         k = L[0][:2] 
         if k not in seen: 
          if k0 is None: 
           k0 = k 
          if k0 == k: 
           store_into_database(L) 
        if k0 is None: 
         break 
        seen.append(k0) 
    

    이 (n는 접두사의 수) 데이터를 통해 n+1 패스를 할 것입니다 만 두 개의 디스크 위치에 접근합니다 (하나 읽기 용과 쓰기 용). 물리적 장치를 분리하면 더 잘 작동합니다.

    추신 : 정말 SQL 데이터베이스가이 문제에 대한 최선의 해결책이라고 확신합니까?

    +0

    고마워요! 한 번에 하나씩 좋은 아이디어입니다. 나는 그것을 시도 할 것이다. 마지막 질문에 대해 : 아니오, 이것이 최선의 방법이라고 확신하지 못합니다. 나는 다른 대안을 생각할 수 없다 ... 너를 할 수 있니? – misha

    +1

    몇 년 전 (PC는 286이었습니다.) 2 백만 건의 게임 (게임 당 평균 70 순위)으로 시작하는 고유 한 체스 위치 데이터베이스를 구축했습니다. 잠시 동안 표준 데이터베이스를 사용하여 벽에 머리를 대고 나면 내가 찾은 솔루션은 사용자 정의 된 파일 형식을 기반으로하고 일종의 입력 데이터 (임의 입력에서 직접 인덱싱 된 데이터 구조를 만들려고 시도하는 것은 하드 디스크 비명). – 6502

    +0

    나는 이런 식으로 끝내었다. 몇 시간 (48 시간 미만)이 걸릴 것이지만 이것은 일회성이므로 기다릴 수 있습니다. – misha

    5
    • 모든 삽입 명령을 단일 트랜잭션으로 랩핑하십시오.
    • 준비된 문을 사용하십시오.
    • 모든 데이터를 삽입 한 후에 만 ​​색인을 만듭니다 (기본 키를 선언하지 않음).
    관련 문제