InnoDB 엔진으로 몇 기가를 입력 한 후 MySQL LOAD DATA INFILE이 80 % 느려짐


14

LOAD DATA INFILE을 통해 100GB 파일을로드하고 있습니다. 나는 몇 시간 동안 MyISAM으로 성공을 거두었습니다.

InnoDB를 사용하여 지금 시도하고 있습니다. 로드는 10MB / 초 이상으로 빠르게 시작됩니다 (테이블 파일 증가를 감시하고 file_per_table켜져 있음).

그러나 약 5GB의 데이터 후에는 2-4MB / sec 범위로 느려집니다. 20GB를 초과하면 약 2MB / 초로 줄었습니다.

InnoDB 버퍼 풀 크기는 8G입니다. 그리고 LOAD DATA INFILE 명령을 실행하기 전에 다음을 수행했습니다.

SET @@session.sql_log_bin=0;
SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;
alter table item_load disable keys;
//Run LOAD DATA INFILE....

나는 그것이 잘 시작하고 시간이 지남에 따라 느려지는 이유를 알 수 없습니다.

또한 동일한 설정을 사용하여 InnoDB와 MyISAM 및 5GB 테스트 데이터 세트를 사용하는 테이블에서 동일한 LOAD DATA INFILE 명령을 실행했는데 MyISAM은 20 배 빨라졌습니다.

InnoDB :

mysql> LOAD DATA CONCURRENT LOCAL INFILE '/tmp/item' REPLACE INTO TABLE item_load;
Query OK, 2630886 rows affected, 6 warnings (21 min 25.38 sec)
Records: 2630886  Deleted: 0  Skipped: 0  Warnings: 6

MyISAM :

mysql> LOAD DATA CONCURRENT LOCAL INFILE '/tmp/item' REPLACE INTO TABLE item_load;
Query OK, 2630886 rows affected, 6 warnings (1 min 2.52 sec)
Records: 2630886  Deleted: 0  Skipped: 0  Warnings: 6

내가 시도해야 할 다른 것이 있습니까? MyISAM 엔진은로드 속도를 훨씬 더 잘 유지할 수 있습니다.


추가 세부 사항:

  • 파일을 개별적으로로드하려고 시도했지만 아무런 차이가 없습니다.

  • 덧붙여서, 나는 각각 500MB의 150 파일을 가지고 있으며, 각 파일 내에 키가 정렬되어 있습니다.

  • 12 시간 후 밤새 40GB를 확보 한 후로드 속도가 0.5MB / 초로 낮아져 실제로는 작동이 불가능합니다.

  • 다른 포럼에서 비슷한 질문에 대한 다른 답변을 찾지 못했습니다 .InnoDB는 대량의 데이터를 몇 GB 크기의 테이블에로드하는 것을 지원하지 않는 것 같습니다.

답변:


7

관찰 # 1

나는 당신이 꺼진 것을 알았습니다 autocommit. 그것은 ibdata1에 많은 양의 데이터를 쌓을 것입니다. 왜?

ibdata1에 저장된 7 가지 정보 클래스가 있습니다.

  • InnoDB 테이블의 데이터 페이지
  • InnoDB 테이블의 인덱스 페이지
  • 데이터 사전
  • 이중 쓰기 버퍼
    • 데이터 손상 방지를위한 안전망
    • 캐싱을위한 OS 우회 지원
  • 버퍼 삽입 (2 차 인덱스 변경 간소화)
  • 롤백 세그먼트
  • 로그 실행 취소
  • 의 그림 표현을 보려면 여기를 클릭하십시오 ibdata1

이 정보 중 일부는 격리 수준에 따라 특정 트랜잭션에 표시됩니다. 이러한 조치는 의도하지 않은 기본 키 잠금많은 팬텀 데이터를 생성 할 수 있습니다 . 이 두 가지가 증가하면 상당히 느려질 것입니다.

권장 사항 : 자동 커밋을 켠 상태

관찰 # 2

나는 당신이 이것을 보았습니다 :

alter table item_load disable keys;

비활성화 키는 InnoDB에서 작동하지 않습니다 . 이유는 다음과 같습니다.

  • MyISAM : DISABLE KEYSMyISAM 테이블의 Secondary Index 업데이트를 종료합니다. 키가 비활성화 된 MyISAM 테이블에 INSERT를 대량 삽입하면 PRIMARY KEY 및 모든 고유 인덱스의 빌드와 함께 빠른 테이블로드가 발생합니다. 실행 ENABLE KEYS하면 모든 보조 인덱스가 테이블에 선형으로 구축되고에 추가됩니다 .MYD.
  • InnoDB : InnoDB의 내부 그림과 같이 시스템 테이블 공간 ibdata1은 2 차 인덱스 삽입 전용 구조를 갖습니다. 현재 MyISAM과 동일한 인덱스를 처리 할 규정이 없습니다.

이를 설명하기 위해 MySQL의 InnoDB 테이블에서 DISABLE KEYS를 실행하려는 시도에 주목하십시오.

mysql> show create table webform\G
*************************** 1. row ***************************
       Table: webform
Create Table: CREATE TABLE `webform` (
  `nid` int(10) unsigned NOT NULL,
  `confirmation` text NOT NULL,
  `confirmation_format` tinyint(4) NOT NULL DEFAULT '0',
  `redirect_url` varchar(255) DEFAULT '<confirmation>',
  `status` tinyint(4) NOT NULL DEFAULT '1',
  `block` tinyint(4) NOT NULL DEFAULT '0',
  `teaser` tinyint(4) NOT NULL DEFAULT '0',
  `allow_draft` tinyint(4) NOT NULL DEFAULT '0',
  `submit_notice` tinyint(4) NOT NULL DEFAULT '1',
  `submit_text` varchar(255) DEFAULT NULL,
  `submit_limit` tinyint(4) NOT NULL DEFAULT '-1',
  `submit_interval` int(11) NOT NULL DEFAULT '-1',
  PRIMARY KEY (`nid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> alter table webform disable keys;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+-------------------------------------------------------------+
| Level | Code | Message                                                     |
+-------+------+-------------------------------------------------------------+
| Note  | 1031 | Table storage engine for 'webform' doesn't have this option |
+-------+------+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select version();
+------------+
| version()  |
+------------+
| 5.5.27-log |
+------------+
1 row in set (0.00 sec)

mysql>

관찰 # 3

MyISAM은 InnoDB보다 20 배 빠르게로드됩니다. 24-25 배 더 빠르기를 원하십니까? 그런 다음 다음을 실행하십시오.

ALTER TABLE item_load ROW_FORMAT=Fixed;

이것은 다른 DDL 변경없이 INSERTs 시간을 20-25 % 빠르게합니다 . 부작용 : MyISAM 테이블의 크기가 80 % -100 % 커질 수 있습니다.

InnoDB 테이블에서도이 기능을 실행할 수 있지만 InnoDB의 ACID 호환 동작MVCC 는 여전히 성능의 병목 현상이 될 수 있습니다. 특히 VARCHAR 필드가 크게 증가한 경우에는에 기록됩니다 ibdata1.


처음 두 가지 관찰은 문제를 처음 발견 한 후에 문제를 해결하기 위해 추가하려고 시도한 것입니다. 첫 번째 시도는 자연스럽게 innodb를 그대로 두는 것입니다 (bin 로깅을 끄십시오). 세 번째 관찰에서 내 데이터 크기는 매우 가변적이며 이것이 문제가 될 것이라고 생각합니까? 나는이 테이블을 myisam으로 유지해야한다고 생각합니다.
David Parks

6

이 질문에 대한 최종 답변은 대규모 참조 테이블에 InnoDB를 사용하지 않는 것입니다. MyISAM은 전체로드에 대해 디스크 속도의 거의 전체 처리량에 가까운 속도로 비명을 지르고 InnoDB는 멈췄다. MyISAM은 간단하지만이 경우이 표의 요구 사항도 마찬가지입니다. LOAD DATA INFILE에 대한 대량로드가있는 간단한 참조 테이블의 경우 지금까지 MyISAM을 사용하는 것이 좋습니다.

그러나 MyISAM 및 InnoDB 테이블을 모두 실행하는 경우 2 개의 캐싱 메커니즘에 대한 메모리 할당을 고려해야합니다. 각 엔진에는 별도의 메모리 할당이 필요한 고유 한 캐싱이 있습니다.


5

입력 파일을 더 작은 청크로 나눌 수 있습니다.

개인적으로 http://www.percona.com/doc/percona-toolkit/2.1/pt-fifo-split.html 을 사용 합니다.

가져 오는 동안 테이블에 대한 테이블 잠금을 받으면 어떻게됩니까? InnoDB의 행 수준 잠금으로 인해 속도가 느려질 수 있습니다 (MyISAM은 테이블 잠금을 사용합니다).

추가 아이디어를 보려면 여기를 읽을 수도 있습니다. http://derwiki.tumblr.com/post/24490758395/loading-half-a-billion-rows-into-mysql


내 파일은 이미 500MB 청크에 있습니다.로드를 쉽게하기 위해 하나의 명명 된 파이프를 통해 파일을 모두 파이프했지만 지금은이 방법을 시도해 보겠습니다.
David Parks

여기에 아무런 차이가 없지만 DB 파일의 11MB / 초 확장에서 6MB (약 2GB 후)의 데이터로 속도가 떨어지고 계속 떨어지고 있습니다. 모든 파일을 for 루프에로드하고 별도의 mysql 호출을로드하고 있습니다.
David Parks

첫 번째 파일은 54 초, 2 번째 3m39s, 3 번째 3m9s, 4m7s, 5m21s 등으로로드되었습니다. 모든 파일의 크기는 동일합니다.
David Parks

2

PK가 AUTO_INCREMENT가 아니거나 csv 파일의 데이터가 PK에서 정렬되지 않은 경우 데이터로드 성능에 영향을 줄 수 있습니다. MySQL의 테이블은 인덱스이므로 모든 데이터가 정렬 된 순서로 저장되므로 PK 값이 AUTO_INCREMENT에 없으면 MySQL이 데이터를 정렬 된 순서로 저장하기 위해 많은 데이터 이동을 수행해야합니다. 이것이 테이블 크기가 커지기 시작할 때 데이터로드가 느려지는 이유입니다.

LOAD DATA INFILE을 사용하여 AUTO_INCREMENT에서 PK로 91GB csv 파일을로드 중이며 처리량이 감소하지 않습니다. 초당 140K ~ 145K 인서트를 받고 있습니다. Percona MySQL 5.6.38 사용

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.