다음 표에 삽입하는 데 최대 70 초가 걸립니다.
CREATE TABLE IF NOT EXISTS `productsCategories` (
`categoriesId` int(11) NOT NULL,
`productsId` int(11) NOT NULL,
PRIMARY KEY (`categoriesId`,`productsId`),
KEY `categoriesId` (`categoriesId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
테이블에는 약 100,000 개의 행이 있으며 디스크에서 7MB를 사용합니다.
쓰기 성능을 향상시킬 수있는 MySQL의 설정이 있습니까?
내 my.cnf
파일은 다음과 같습니다.
log-slow-queries="/var/log/mysql/slow-query.log"
long_query_time=1
log-queries-not-using-indexes
innodb_buffer_pool_size=4G
innodb_log_buffer_size=4M
innodb_flush_log_at_trx_commit=2
innodb_thread_concurrency=8
innodb_flush_method=O_DIRECT
query_cache_size = 6G
key_buffer_size = 284M
query_cache_limit = 1024M
thread_cache_size = 128
table_cache = 12800
sort_buffer_size=2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
read_buffer_size=128K
open_files_limit = 1000
table_definition_cache = 1024
table_open_cache = 6000
max_heap_table_size=512M
tmp_table_size=4096M
max_connections=1000
thread_concurrency = 24
하드웨어 설정은 다음과 같습니다.
- 델 R710
- RAID10
- 48G RAM
이 하드웨어가 주어지면 문제가 하드웨어 병목 현상이 될 것으로 기대하지 않습니다.
답변
관찰 # 1
내 눈길을 끄는 첫 번째 것은 테이블 구조입니다
CREATE TABLE IF NOT EXISTS `productsCategories` (
`categoriesId` int(11) NOT NULL,
`productsId` int(11) NOT NULL,
PRIMARY KEY (`categoriesId`,`productsId`),
KEY `categoriesId` (`categoriesId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
통지를하시기 바랍니다 categoriesId
인덱스와 PRIMARY KEY는 동일한 열로 시작합니다. 중복 인덱스입니다. 이 테이블은 InnoDB이므로 categoriesId
인덱스는 다른 이유로 중복됩니다. 모든 보조 인덱스에는 gen_clust_index에 대한 키가 포함됩니다 (일명 Clustered Index; mysql에서 gen_clust_index는 무엇을 참조하십시오 ).
categoriesId
색인 을 제거하면
ALTER TABLE productsCategories DROP INDEX categoriesId;
이 경우 보조 및 클러스터형 인덱스 유지 관리를 추가로 수행 할 필요가 없으므로 INSERT가 크게 향상됩니다 .
관찰 # 2
대량 삽입 작업을 수행하는 경우 큰 대량 삽입 버퍼 가 필요합니다 .
이것에 대한 내 과거 게시물을 참조하십시오 :
- https://dba.stackexchange.com/a/16979/877
- https://dba.stackexchange.com/a/9893/877
- https://dba.stackexchange.com/a/2948/877
관찰 # 3
로그 파일 크기가 너무 작습니다! InnoDB 버퍼 풀의 25 % 여야하며,이 경우 1G 여야합니다. InnoDB 로그 파일 크기를 조정하는 방법에 대한 내 게시물을 참조하십시오 .
관찰 # 4
innodb_thread_concurrency를 설정하지 마십시오! 나는 Percona Live NYC에서 직접 그 환경을 떠나는 것을 배웠다 . MySQL 5.5, MySQL 5.1 InnoDB 플러그인 및 Percona Server 5.1 이상에서는 기본적으로 비활성화되어 있습니다.
관찰 # 5
innodb_file_per_table을 사용해야합니다. 이것이 비활성화되면 ibdata1의 파일 유지 관리를 악몽으로 만듭니다. 이를 구현하기 위해 InnoDB를 정리하는 방법에 대한 내 게시물을 읽으십시오 .
관찰 # 6
MySQL 5.5 또는 Percona Server를 사용하는 경우 InnoDB가 다중 CPU / 다중 코어를 사용하도록 특정 옵션을 설정해야합니다. 해당 설정에 대한 내 게시물을 참조하십시오 .
관찰 # 7
당신은 있습니다 innodb_log_buffer_size=4M
. 기본값은 8M입니다. 이로 인해 리두 로그가 두 배로 플러시됩니다. 그것은 또한 당신의 innodb_flush_log_at_trx_commit=2
설정을 방해 할 것 입니다. 32M으로 설정하십시오. 또한 innodb_log_buffer_size의 MySQL 설명서 를 참조하십시오 .
이러한 관찰에 비추어 다음 설정을 추가하거나 교체하십시오.
[mysqld]
innodb_thread_concurrency = 0
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000
innodb_file_per_table
innodb_log_file_size=1G
innodb_log_buffer_size=1G
bulk_insert_buffer_size = 256M
답변
당신은 확인해야합니다 innodb_log_file_size
기본 설정은 쓰기 집약적 설정에 대한 매우 낮은 5M입니다. 100M으로 설정하십시오. ib_logfile*
새로운 설정으로 DB를 시작하려면 이전 파일 을 삭제해야합니다 . DB 서버가 실행되는 동안 로그 파일을 삭제하지 마십시오. 먼저 로그 파일을 중지해야합니다. 아마도 오래된 로그 파일을 삭제하는 것이 아니라 먼저 백업해야합니다.