programing

mysql LOAD DATA/mysqlimport 성능 향상?

bestcode 2023. 1. 21. 09:47
반응형

mysql LOAD DATA/mysqlimport 성능 향상?

일괄 처리 중입니다.CSV15 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

반응형