MySQL INSERT 및 UPDATE 성능을 향상시키는 방법은 무엇입니까?


14

이 질문은 아마도 StackOverflow에서도 요청할 수 있지만 먼저 여기에서 시도 할 것입니다 ...

데이터베이스에서 INSERT 및 UPDATE 문의 성능이 저하되어 웹 앱의 성능이 저하되는 것으로 보입니다.

테이블은 InnoDB이며 응용 프로그램은 트랜잭션을 사용합니다. 작업 속도를 높이기 위해 쉽게 조정할 수있는 방법이 있습니까?

잠금 문제가있는 것 같습니다. 어떻게 알 수 있습니까?


dba.stackexchange.com에서 개선
Pacerier

답변:


25
  1. 하드웨어 및 OS가 올바르게 구성 및 조정되었는지 확인하십시오.

    • 문제의 원인 (CPU / IO / 메모리 / 스왑 사용). IOP가 많습니까? CPU가로드 되었습니까? 읽기 IOP가 많으면 InnoDB buffer_pool이 충분하지 않을 수 있습니다. CPU가로드 된 경우 쿼리는 적절한 인덱스를 사용하는 대신 전체 테이블 스캔을 수행합니다.
    • 디스크 / RAID / LVM 설정. 일부 특정 설정에서 LVM 스트라이핑 은 디스크로드를 균등화하여 이점을 제공 할 수 있습니다 (하드웨어 RAID 없음, 다중 LUN 연결)
    • IO 스케줄러 : 좋은 하드웨어 RAID 컨트롤러가 있으면 아마도 noop이 가장 좋습니다. RedHat은 몇 가지 테스트를 거쳤 으며 Oracle (및 기타 DB) CFQ가 최선의 선택이라고 말했습니다. tpc-c 또는 tpc-e와 같은 일부 벤치 마크를 실행하고 하드웨어에 가장 적합한 것을 선택해야합니다.
    • 올바른 파일 시스템-ext3은 데이터베이스 별 워크로드에서 제대로 수행되지 않습니다. XFS 또는 OCFS2가 더 좋습니다. 다시 벤치 마크가 필요합니다.
    • 시스템이 스왑을 사용하는지 살펴보십시오. swap을 사용하면 mysql 성능이 저하됩니다 .
  2. MySQL / InnoDB 인스턴스가 올바르게 조정되었는지 확인하십시오.

    • 버퍼 풀 크기-메모리의 캐시 데이터 페이지
    • innodb_flush_method = O_DIRECT-이중 IO 버퍼링 방지
    • InnoDB 로그 파일 크기 증가-쓰기 집약적 인 워크로드의 경우 성능이 향상 될 수 있습니다. 그러나 로그 파일 크기가 클수록 충돌 복구 시간이 길어집니다. 때때로 몇 시간 안에 !!!
    • innodb_flush_log_at_trx_commit = 0 또는 2-ACID에 대해 걱정하지 않고 마지막 1 초 또는 2 초 동안 트랜잭션을 잃을 수있는 경우.
    • key_buffer_size-MyISAM에 매우 중요하지만 디스크 임시 테이블에 사용됩니다.
    • 시계 INNODB 상태
  3. 워크로드 분석-모든 쿼리를 포착하여 로그를 느리게 쿼리하고 mk-query-digest를 실행하십시오. tcpdump 및 maatkit을 사용하여 모든 쿼리를 잡을 수 있습니다
    • 대부분의 서버 시간이 걸리는 쿼리는 무엇입니까?
    • 임시 테이블, 특히 큰 임시 테이블이 작성됩니까?
    • 설명 사용법을 배우십시오
    • 애플리케이션이 트랜잭션을 사용합니까? autocommit = 1 (기본값 : MySQL)로 쿼리를 실행하면 모든 삽입 / 업데이트 쿼리가 새 트랜잭션을 시작하여 약간의 오버 헤드가 발생합니다. 가능하다면 자동 커밋을 비활성화하고 (파이썬 MySQL 드라이버에서 자동 커밋은 기본적으로 비활성화되어 있습니다) 모든 수정이 완료된 후 커밋을 수동으로 실행하십시오.
    • 응용 프로그램이 루프에서 동일한 테이블에 일련의 삽입을 수행합니까? Load data infile명령은 일련의 인서트에 훨씬 빠릅니다.
    • 기억하십시오 : select count(*) from table;myisam보다 innodb의 속도가 훨씬 느립니다.
    • 대부분의 서버 시간에 어떤 유형의 INSERT / UPDATE 쿼리가 필요합니까? 어떻게 최적화 할 수 있습니까?
    • DB에 적절한 인덱스가 있는지 확인하고 필요한 경우 추가하십시오.

우리 환경에서는 한 가지 유형의 업데이트 쿼리가 느리다는 상황이있었습니다. 배치 작업 완료 예상 시간은 2 일입니다 !!! 느린 쿼리 로그를 분석 한 후이 유형의 업데이트 쿼리를 완료하는 데 4 초가 소요됩니다. 쿼리는 다음과 같습니다 update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zz. 업데이트 쿼리를 선택 쿼리로 변환하고 찾은 선택 쿼리에 대해 Explain을 실행 한 후이 유형의 쿼리는 인덱스를 사용하지 않습니다. 적절한 인덱스를 생성 한 후 업데이트 쿼리 실행 시간을 밀리 초로 줄이고 전체 작업을 2 시간 이내에 완료했습니다.

유용한 링크들 :


모든 체크 인덱스 전에. "지표를 매수하지 않기 때문에 테이블이 커질수록"과 같은 SMELL의 성능이 저하됩니다.
TomTom

5

기본 innoDB 설정을 사용하면 트랜잭션을 디스크에 쓰고 플러시 할 수있는 속도로 제한됩니다. 약간의 ACID 손실을 처리 할 수 ​​있으면 innodb_flush_log_at_trx_commit을 실험하십시오. 약 1 초마다 로그를 디스크에 쓰고 플러시하려면 0으로 설정하십시오. 커밋 할 때마다 쓰고 플러시하려면 1 (기본값)로 설정하십시오. 모든 커밋 후에 로그 파일에 쓰지만 초당 1 회만 플러시하려면 2로 설정하십시오.

1 번의 트랜잭션 손실을 처리 할 수 ​​있으면 쓰기 성능을 크게 향상시킬 수 있습니다.

또한 디스크의 작업에주의하십시오. RAID 10> RAID 5는 추가 디스크 비용으로 쓰기 작업을 수행합니다.


1

잠금 문제는 다음의 연결 상태로 표시됩니다. show full processlist;

my.cnf및 MySQL 설명서를 읽으십시오 . 구성 옵션은 매우 잘 문서화되어 있습니다.

일반적으로, 가능한 많은 메모리에서 처리되기를 원합니다. 쿼리 최적화를 위해서는 임시 테이블을 피해야합니다. 인덱스의 올바른 적용.

튜닝은 선호하는 데이터베이스 엔진 및 응용 프로그램 아키텍처에 따라 다릅니다. 인터넷 검색에 이미 존재하는 상당한 리소스가 있습니다.



0

InnoDB는 꽤 좋은 엔진입니다. 그러나 '조정'에 크게 의존합니다. 한 가지 사항은 삽입이 기본 키를 늘리는 순서가 아닌 경우 innoDB가 MyISAM보다 약간 오래 걸릴 수 있다는 것입니다. 더 높은 innodb_buffer_pool_size를 설정하면이를 쉽게 극복 할 수 있습니다. 내 제안은 총 RAM의 60-70 %로 설정하는 것입니다. 현재 프로덕션에서 이러한 서버 4 대를 실행하고 있으며 분당 약 350 만 행을 삽입합니다. 그들은 이미 3 테라 바이트에 가깝습니다. InnoDB는 높은 동시 삽입 때문에이어야했습니다. 인서트 속도를 높이는 다른 방법이 있습니다. 그리고 나는 일부를 벤치마킹했습니다.


0

Java에서 자동 커밋 및 변경 사항을 한 번만 비활성화하면 웹 응용 프로그램에서 MySQL의 삽입 및 업데이트 성능 문제를 해결하는 방법. mysql 문서에서 제안한대로.

MySQL 문서

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