mysql LOAD DATA/mysqlimport 성능 향상?
일괄 처리 중입니다.CSV
15 GB (30 mio 행)에서mysql-8
데이터베이스입니다.
문제: 작업은 약 20분 소요되며, accessy throughput은 15~20MB/s입니다.하드 드라이브는 150 MB/s의 파일을 전송할 수 있습니다.
20GB의 RAM 디스크가 있으며, 이 디스크에 csv가 저장되어 있습니다.다음과 같이 Import합니다.
mysqlimport --user="root" --password="pass" --local --use-threads=8 mytable /tmp/mydata.csv
이 방법에서는LOAD DATA
보닛 밑에대상 테이블에는 인덱스가 없지만 100개 정도의 열이 있습니다(변경할 수 없습니다).
이상한 점:다음과 같이 몇 가지 설정 파라미터를 조정해 보았습니다./etc/mysql/my.cnf
단, 대폭적인 개선은 이루어지지 않았습니다.
log_bin=OFF
skip-log-bin
innodb_buffer_pool_size=20G
tmp_table_size=20G
max_heap_table_size=20G
innodb_log_buffer_size=4M
innodb_flush_log_at_trx_commit=2
innodb_doublewrite=0
innodb_autoinc_lock_mode=2
질문:LOAD DATA
/mysqlimport
이러한 설정 변경을 존중할 수 있습니까?아니면 우회하는 건가요?아니면 올바른 설정 파일을 사용하고 있는 건가요?
변수 중 적어도 하나를 선택하면 mysql 서버에 의해 올바르게 로드되었음을 알 수 있습니다.예를들면show variables like 'innodb_doublewrite'
드라마들.OFF
어쨌든, 어떻게 하면 수입 속도를 더 높일 수 있을까요?아니면 데이터베이스가 병목현상이 되어 15~20MB/s 임계값을 극복할 방법이 없는 것일까요?
업데이트: 흥미롭게도 하드 드라이브에서 ramdisk로 csv를 가져오면 성능은 거의 비슷합니다(약간 더 낫지만 25MB/s를 초과한 적은 없습니다).같은 수의 행을 테스트했지만 몇 개의 열만 테스트했습니다.80MB/s 정도가 됩니다.열 수가 병목현상이란 게 확실해요?하지만 더 많은 열이 이 프로세스를 지연시키는 이유는 무엇입니까?
MySQL/MariaDB 엔진은 대량 삽입 시 병렬화가 거의 없습니다.CPU 코어는 1개당 1개만 사용할 수 있습니다.LOAD DATA
진술.로드 시 CPU 사용률을 감시하여 1개의 코어가 완전히 사용되고 출력 데이터의 양이 한정되어 디스크 스루풋이 충분히 활용되지 않는 것을 확인할 수 있습니다.
MySQL 의 최신 버전에는, https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-utilities-parallel-table.html 의 새로운 병행 로드 기능이 있습니다.유망해 보이지만 아직 많은 피드백을 받지 못한 것 같습니다.그게 당신 경우에는 도움이 될지 모르겠네요.
다음 설정 파라미터에서 값을 높게 설정할 것을 권장하는 다양한 체크리스트를 인터넷에서 확인했습니다.log_buffer_size
,log_file_size
,write_io_threads
,bulk_insert_buffer_size
하지만 비교 테스트를 실행했을 때 이점은 그다지 뚜렷하지 않았습니다(아마 10~20% 더 빠를 것입니다).innodb_buffer_pool_size
충분히 크다).
이게 정상일 수도 있어요다음 절차에 대해 설명하겠습니다.
- csv 파일을 RAM 디스크에서 읽고 있으므로 IOP는 사용되지 않습니다.
- InnoDB를 사용하시나요?이 경우 데이터는 buffer_pool로 들어갑니다.블록이 만들어질 때 디스크에 플러싱할 수 있도록 '더러운' 표시가 되어 있습니다.
- buffer_pool은 크지만 테이블 크기만큼 크지는 않을 수 있으므로 모든 데이터 읽기를 완료하기 전에 일부 블록을 플래시해야 합니다.
- 모든 데이터를 읽고 테이블이 완료된 후 더티 블록이 점차 디스크로 플러시됩니다.
- 고유하지 않은 인덱스가 있는 경우 마찬가지로 디스크에 지연된 방식으로 작성됩니다(cf '변경 버퍼링').기본적으로는 change_buffer는 buffer_pool의 25%를 차지합니다.
결과 테이블의 크기는 얼마나 됩니까?CSV 파일의 15GB보다 훨씬 크거나 더 작을 수 있습니다.
디스크로 데 ?csv "RAM " " " " 。는 그것이 했다고 합니다.LOAD DATA
될 수 I/O를 사용하다
이에요.SHOW GLOBAL VARIABLES LIKE 'innodb%';
; 관련될 수 있는 다른 몇 가지가 있습니다.
더
이것들은 끔찍합니다.
tmp_table_size=20G
max_heap_table_size=20G
복잡한 문의가 있는 경우 RAM에 20GB를 여러 번 할당할 수 있습니다.RAM의 1% 미만으로 유지합니다.
하드디스크에서 RAM디스크로 csv 복사가 느리면 150MB/s의 유효성을 의심합니다.
6시간에 한 번 테이블을 로드하고 수행에 1/3시간이 걸린다면 더 빨리 할 필요는 없을 것 같습니다.OTOH, 알아볼 만한 게 있을지도 몰라테이블 잠금이 원인이 되어 다운타임이 20분인 경우 다음과 같이 쉽게 제거할 수 있습니다.
CREATE TABLE t LIKE real_table;
LOAD DATA INFILE INTO t ...; -- not blocking anyone
RENAME TABLE real_table TO old, t TO real_table; -- atomic; fast
DROP TABLE old;
언급URL : https://stackoverflow.com/questions/58305653/improve-performance-of-mysql-load-data-mysqlimport
'programing' 카테고리의 다른 글
목록을 2개씩 반복하려면 어떻게 해야 하나요? (0) | 2023.01.21 |
---|---|
목록에서 가장 긴 문자열을 선택하는 Python의 가장 효율적인 방법? (0) | 2023.01.21 |
팬더 데이터 프레임 목록 연결 (0) | 2023.01.21 |
MySQL 문자열에서 영숫자가 아닌 모든 문자를 제거하려면 어떻게 해야 합니까? (0) | 2023.01.21 |
PHP | define() vs. const. (0) | 2023.01.21 |