'LOAD DATA INFILE'이 일반 INSERT 문보다 빠른 이유는 무엇입니까?


22

csv 파일에서 읽고 데이터베이스에 데이터를 삽입하는 문 을 사용하여 초당 60,000 개의 삽입을 달성 할 수 있다고 언급 한 기사를 읽었 LOAD DATA IN FILE습니다.

일반 인서트와 다른 이유는 무엇입니까?

편집 :
나는 하나의 INSERT진술 만 호출하여 왕복을 줄였습니다 .

INSERT INTO tblname
VALUES (NULL,2,'some text here0'),(NULL,2,'some text here1')
    ,(NULL,2,'some text here2'),(NULL,2,'some text here3')
    .....,(NULL,2,'some text here3000');

이건 어때?


나는 대 확장 삽입을 벤치마킹, 중간에 기사를 썼다 LOAD DATA INFILE: MySQL의 고속 삽입 . 결론 : LOAD DATA INFILE확장 인서트 사용 성능의 65 %를 달성 할 수 있습니다 . 최신 하드웨어에 초당 240,000 개의 삽입물이 있습니다.
Benjamin

답변:


26

LOAD DATA INFILE과 확장 INSERT는 각각 고유 한 장점이 있습니다.

LOAD DATA INFILE은 다음과 같은 팅을 수행하기 위해 벨 및 휘파람과 함께 단일 조작으로 테이블 데이터를 대량로드하도록 설계되었습니다.

  • 초기 줄 건너 뛰기
  • 특정 열 건너 뛰기
  • 특정 열 변환
  • 특정 열로드
  • 중복 된 주요 문제 처리

구문 분석에 필요한 오버 헤드가 적습니다.

반면 1,000,000 개의 행 대신 100 개의 행만 가져 오는 경우 확장 된 INSERT가 가능합니다.

mysqldump는 INSERT 당 수백 또는 수천 행의 주입을 수행 할 때 데이터와 함께 테이블 디자인을 수행하기 위해 확장 INSERT를 중심으로 설계되었습니다. LOAD DATA INFILE은 항상 스키마와 데이터 사이에 물리적 이분법을 만듭니다.

응용 프로그램 관점에서 LOAD DATA INFILE은 확장 INSERT보다 스키마 변경에 더 민감하지 않습니다.

LOAD DATA INFILE을 사용하는 것의 장점, 나쁜 점 및 추악한 점을왔다 갔다 할 수 있습니다. 어떤 기술을 사용하든 항상 bulk_insert_buffer_size를 설정해야합니다 . 왜?

bulk_insert_buffer_size의 MySQL 설명서에 따르면 :

MyISAM은 특수 트리와 같은 캐시를 사용하여 비어 있지 않은 데이터를 추가 할 때 INSERT ... SELECT, INSERT ... VALUES (...), (...), ... 및 LOAD DATA INFILE에 대한 대량 삽입을 더 빠르게 만듭니다. 테이블. 이 변수는 캐시 트리의 크기를 스레드 당 바이트 수로 제한합니다. 0으로 설정하면이 최적화가 비활성화됩니다. 기본값은 8MB입니다.

몇 년 동안 클라이언트가 이것을 설정하지 않고 8MB로 남겨둔 후 클라이언트를 보았습니다. 그런 다음 LOAD DATA INFILE을 사용하거나 mysqldump를 가져 오기로 결정할 때 잘못된 것을 감지 할 수 있습니다. 보통 이것을 보통 256M으로 설정하는 것이 좋습니다. 어떤 경우에는 512M입니다.

충분히 큰 대량 INSERT 버퍼가 있으면 두 기술 중 하나를 사용하여 학업을 수행하고 개인적인 선택으로 귀결됩니다. 요청시 단 100 개의 행만 INSERT하는 응용 프로그램의 경우 확장 INSERT를 사용하십시오.

공평하게 말하면, LOAD DATA INFILE이 구성을 고려하지 않았기 때문에 일반적인 INSERT 문이로드 된 명령문과 같이 빠를수록 빠릅니다. 적절한 bulk_insert_buffer_size를 사용하여 LOAD DATA INFILE과 확장 된 INSERT간에 벤치 마크를 설정하더라도 각 행을 구문 분석 할 때 저장된 나노초는 LOAD DATA INFILE에 유리하게 공칭 결과 만 산출 할 수 있습니다.

계속해서 이것을 my.cnf에 추가하십시오

[mysqld]
bulk_inset_buffer_size=256M

확장 INSERT를 시작하기 전에 세션에 대해서만 설정할 수도 있습니다.

SET bulk_insert_buffer_size= 1024 * 1024 * 256;

업데이트 2012-07-19 14:58 EDT

관점을 유지하기 위해 대량 삽입 버퍼는 InnoDB가 아닌 MyISAM 테이블을로드 할 때만 유용합니다. InnoDB 대량로드에 대한 최신 게시물을 작성했습니다 : Infile의 Mysql로드가 하드 드라이브 대기 대기


4

대부분의 데이터베이스 관리 시스템에는 대량의 데이터를 빠르게로드하기위한 대량로드 기능이 있습니다. INSERT, 자원의 잠금, 트랜잭션 경계 설정, 참조 무결성 검사, 할당 I / O 당 문으로 수행되어야 함 - 문은 중요한 당 문 수하물의 양을 가지고있다.

대량 삽입 작업으로 프로세스가 간소화되므로 행당 오버 헤드가 훨씬 줄어 듭니다. DBMS는 insert 문을 통하는 것보다 훨씬 빠른 속도로 데이터를 대량로드 할 수 있습니다.


3

개별 INSERT문을 구문 분석하고 실행 하면 CSV 파일을 열로 분할하여 직접로드하는 것보다 훨씬 더 많은 오버 헤드가 발생합니다.

INSERT명령문은 MySQL 엔진에 의해 개별적으로 구문 분석되고 유효성을 검사해야합니다. 이는 추가 CPU 자원을 소비하고 더 많은 클라이언트 <> 서버 왕복이 필요합니다. 를 통해 대량로드 할 때는이 작업이 필요하지 않습니다 LOAD DATA INFILE. LOAD DATA INFILE빈 테이블에로드 할 때 사용할 수있는 최적화도 있습니다 . 자세한 내용은 이 링크 를 참조하십시오.


내 질문의 편집 부분을 참조하십시오.
ALH

준비된 명령문을 사용할 때 구문 분석 오버 헤드가 없습니다.
Benjamin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.