source

MyISAM에 비해 TokuDB와 InnoDB 삽입이 느린 이유

gigabyte 2022. 11. 28. 21:12
반응형

MyISAM에 비해 TokuDB와 InnoDB 삽입이 느린 이유

MyISAM, InnoDB, TokuDB의 퍼포먼스 동작을 비교하기 위해 다음과 같은 SQL 문을 준비했습니다(INSERT는 100,000회 실행).

MyISAM:

CREATE TABLE `testtable_myisam` (`id` bigint(20) NOT NULL AUTO_INCREMENT, `value1` INT DEFAULT NULL, `value2` INT DEFAULT NULL, PRIMARY KEY (`id`), KEY `index1` (`value1`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `testtable_myisam` (`value1`, `value2`) VALUES (FLOOR(RAND() * 1000), FLOOR(RAND() * 1000)); 

InnoDB:

CREATE TABLE `testtable_innodb` (`id` bigint(20) NOT NULL AUTO_INCREMENT, `value1` INT DEFAULT NULL, `value2` INT DEFAULT NULL, PRIMARY KEY (`id`), KEY `index1` (`value1`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `testtable_innodb` (`value1`, `value2`) VALUES (FLOOR(RAND() * 1000), FLOOR(RAND() * 1000));

TokuDB:

CREATE TABLE `testtable_tokudb` (`id` bigint(20) NOT NULL AUTO_INCREMENT, `value1` INT DEFAULT NULL, `value2` INT DEFAULT NULL, PRIMARY KEY (`id`), KEY `index1` (`value1`)) ENGINE=TokuDB DEFAULT CHARSET=utf8;

INSERT INTO `testtable_tokudb` (`value1`, `value2`) VALUES (FLOOR(RAND() * 1000), FLOOR(RAND() * 1000));

InnoDB의 INSERT 성능은 MyISAM보다 50배 가까이 느리고 TokuDB는 MyISAM보다 40배 정도 느립니다.

다음으로 InnoDB의 innodb-syslog-at-trx-commit=2의 설정을 파악하여 MyISAM과 같은 INSERT 동작을 합니다.

문제는 TokuDB에서 무엇을 해야 하는가 하는 것입니다.TokuDB의 INSERT 성능 저하도 잘못된 설정에 의한 것이라고 생각합니다만, 그 원인을 알 수 없습니다.

--------- UPDATE -----------

tmcallaghan의 코멘트에 의해 설정을 「tokudb_commit_sync=OFF」로 변경했습니다만, 작은 데이터 세트에 TokuDB의 삽입 레이트는 의미가 있는 것 같습니다(다음의 문제가 발견되면 큰 데이터 세트에 대해 실행합니다).

단, TokuDB의 선택된 퍼포먼스는 MyISAM 및 InnoDB에 비해 다음 SQL과 비교해도 유선 접속되어 있습니다(여기서?는 내 시뮬레이터에 의해 다른 Int로 대체됩니다).

SELECT id, value1, value2 FROM testtable_myisam WHERE value1=?; 
SELECT id, value1, value2 FROM testtable_innodb WHERE value1=?; 
SELECT id, value1, value2 FROM testtable_tokudb WHERE value1=?; 

100만 개의 데이터셋에 대해 MyISAM과 InnoDB는 각각 10k SELECT 스테이트먼트에 10초와 15초가 소요되지만 TokuDB에는 약 40초가 소요됩니다.

다른 설정을 놓쳤나요?

잘 부탁드립니다!

그다지 흥미로운 테스트라고는 생각되지 않지만(100,000 행은 많지 않고 삽입도 동시적이지 않습니다) 원하는 설정은 다음과 같습니다.

"set tokudb_commit_sync=0;"을 발행하면 커밋 작업에서 fsync()가 꺼집니다.이 모드에서는 내구성이 보증되지 않습니다.

TokuDB의 강점은 앞서 말한 바와 같이 RAM보다 상당히 큰 데이터를 인덱싱하는 것이지만 이번 테스트는 그렇지 않습니다.

트랜잭션엔진이 느린 이유는 하드디스크에 강제로 데이터를 기록하도록 하기 때문입니다.HDD가 데이터를 기록하려면 헤드를 자기 디스크 플레이트에 놓고 데이터를 스트리밍해야 합니다.각 트랜잭션은 디스크가 자기 바늘을 머리 위에 놓고 데이터를 적어 OS에 확실하게 전달한다는 것을 의미합니다.

트랜잭션엔진이 이렇게 하는 이유는 ACID의 D 부분에 적합하기 때문입니다.기록하고자 하는 데이터가 실제로 영구적으로 기록되도록 보장합니다.MyISAM은 그런 거 안 해요.

따라서 삽입 속도는 하드 디스크의 IOPS(Input Output Operations per Second) 수에 비례합니다.즉, 한 트랜잭션에 여러 쿼리를 래핑할 경우 언급된 드라이브의 쓰기 속도 대역을 이용할 수 있습니다.또한 IOPS가 높은 드라이브(예: SSD의 IOPS는 40,000이 넘고 기계식 드라이브의 IOPS 범위는 약 250 - 300이지만 정확한 수치는 아닙니다)를 의미합니다.

간단히 말하면 트랜잭션 엔진을 사용하여 정말 빠르게 삽입하고 싶다면 여러 쿼리를 하나의 트랜잭션으로 묶으십시오.엔진은 버퍼로 사용할 수 있는 다양한 고속 메모리를 이용하려고 하기 때문에 모든 "최적화"는 ACID의 D 부분을 약간 위반하는 것입니다.즉, 전원이 꺼지는 등 문제가 발생하면 데이터에 작별 인사를 해야 합니다.

또한, 당신이 실시한 검사는 규모가 작기 때문에 실제로는 나쁜 것입니다.InnoDB와 특히 TokuDB는 모두 수백 기가바이트의 데이터를 포함하고 선형 성능을 제공하도록 설계되었습니다.

my.cnf를 아래와 같이 업데이트했습니다만, 전체적인 퍼포먼스가 좋아졌습니다.

MyISAM에서 SELECT를 10k회 사용할 경우, InnoDB는 5초, TokuDB는 8초가 소요됩니다.그래서 결론적으로 말하면, TokuDB는 MyISAM과 InnoDB와 마찬가지로 동작하고 있습니다(필요하지는 않습니다).

InnoDB v.s.의 퍼포먼스 비교가 매우 궁금합니다.TokuDB(MyISAM v.s.는 제외).TokuDB, 왜?


tokudb_commit_sync=0

max_allowed_packet = 1M
table_open_cache = 128
read_buffer_size = 2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size = 32M
thread_concurrency = 8

innodb_flush_log_at_trx_commit=2
innodb_buffer_pool_size = 2G
innodb_additional_mem_pool_size = 20M
innodb_log_buffer_size = 8M
innodb_lock_wait_timeout = 50

언급URL : https://stackoverflow.com/questions/21863823/why-tokudb-and-innodb-insert-is-so-slow-compared-to-myisam

반응형