MyISAM에서 InnoDB 로의 전환 속도 향상


15

약 450 테이블의 데이터베이스가 있고 4GB를 차지하는 mysql 5.1 서버가 있습니다. 이 표의 대부분 (2 개를 제외하고)은 MyIsam입니다. 대부분의 경우 문제가 없었지만 (트랜잭션 필요 없음) 응용 프로그램에서 트래픽이 증가했으며 특정 테이블이 업데이트시 테이블 잠금으로 인해 영향을 받았습니다. 이것이 바로 테이블 중 2 개가 InnoDB 인 이유입니다.

작은 테이블 (100k 행)의 변환은 전혀 오래 걸리지 않으므로 가동 중지 시간이 최소화됩니다. 그러나 내 추적 테이블 중 일부가 5 천만 행에 접근하고 있습니다. ALTER TABLE...ENGINE InnoDB큰 테이블 에서 속도를 높이는 방법이 있습니까? 그렇지 않은 경우 이러한 쓰기가 많은 테이블에서 가동 중지 시간을 최소화하는 다른 방법이 있습니까?


1
염두에 두어야 할 사항 : 한 게시물에 여러 개의 질문이 있으면 질문 중 하나에 답변을 게시 할 수없는 사람들을 실망시키는 경향이 있습니다.
BenV

나는 대답하기가 다소 복잡하기 때문에 VtC. 몇 가지 질문으로 개별적으로 열어야합니다.
jcolebrand

기꺼이 조언을 받아 단일 질문으로 만들지 만이 질문을 삭제하고 새 질문을 여는 것이 좋습니다. 다시 쓰기는 대부분 두 번째 글 머리 기호를 제거하고 첫 번째 글 머리 기호를 변경합니다 (어떤 스토리지 엔진을 반영하기 위해 제목을 업데이트했습니다)
Derek Downey

어느 쪽이든 괜찮을 것입니다. 일반적으로 다른 두 가지 질문을 작성하고 삭제하는 것이 더 쉽습니다 . 그러나 "참조"로이 것을 그대로두고 "이것이 나의 전반적인 목표입니다"라는 질문으로 다른 두 개를 다시 참조하도록 할 수 있습니다.
jcolebrand

이 글을 하나의 글 머리 기호로 수정 한 다음 후속 질문을 게시하십시오.
Brian Ballsun-Stanton

답변:


10

내가 ALTER를 싫어한다는 말로 시작하겠습니다. 사악하다, IMHO.

현재 테이블 스키마입니다.

CREATE TABLE my_table_of_love (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=MyISAM CHARSET=utf8;

추천하는 경로는 다음과 같습니다.

이전 테이블 오브젝트를 대체 할 새 테이블 오브젝트를 작성하십시오.

CREATE TABLE my_table_of_love_NEW (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=InnoDB CHARSET=utf8

이전 테이블의 모든 행을 이름별로 새 테이블에 삽입하십시오.

INSERT INTO my_table_of_love_NEW (id,my_value,date_created)
SELECT id,my_value,date_created FROM my_table_of_love;

마이그레이션 연기 테스트 :

SELECT COUNT(*) FROM my_table_of_love_NEW;
SELECT COUNT(*) FROM my_table_of_love;
SELECT a.id,a.my_value,a.date_created FROM my_table_of_love_NEW a
LEFT JOIN my_table_of_love b ON (b.id = a.id)
WHERE a.my_value != b.my_value;

롤백해야 할 경우 백업을 유지할 수 있도록 테이블 이름을 교체하십시오.

RENAME TABLE my_table_of_love TO my_table_of_love_OLD;
RENAME TABLE my_table_of_love_NEW TO my_table_of_love;

회귀 테스트로 진행하십시오.

이 방법은 여러 인덱스와 수백만 행이있는 테이블에서 점점 더 선호됩니다.

생각?


1
동의합니다 ... 트랜잭션이 많이 발생 하더라도이 작업을 수행하는 동안 데이터베이스를 중단해야 할 수도 있습니다. (그러나 대체 테이블은 더 긴 다운 타임을 제공 할 것입니다.)
Joe

예, 더 활동적인 테이블에 가동 중지 시간이 필요할 것이라고 생각했습니다. 몇 가지 테스트를 수행해야하지만 왜 5 천만 행 ALTER TABLE보다 오래 걸립 INSERT INTO...SELECT니까?
데릭 다우니

그렇지 않습니다. 기본적으로 MySQL은이 포스터가 제안한대로 내부적으로 정확하게 수행합니다. 정의의 사본을 작성하고 사본에 세류를로드합니다.
모건 토커

이 방법은 "tmp에 복사"부분을 건너 뛰기 때문에 큰 테이블에 시간이 걸릴 수 있기 때문에이 방법이 마음에 듭니다.
Haluk

MySQL 5.7에서 ALTER가 훨씬 더 빠르고 쉽게 대처할 수 있다는 점을 추가하겠습니다.
randomx

7

1) 손실 보호는 편집증의 기능입니다. 항상 백업하십시오. 정말 편집증이라면 백업을 한 다음 백업에서 복원하십시오.

2) MySQL 매뉴얼 의이 페이지 에는 테이블 유형을 변환하는 지침이 있습니다.

테이블을 InnoDB로 변경하는 가장 빠른 방법은 InnoDB 테이블에 직접 삽입하는 것입니다. 즉, ALTER TABLE ... ENGINE = INNODB를 사용하거나 동일한 정의로 빈 InnoDB 테이블을 작성하고 INSERT INTO ... SELECT * FROM ...을 사용하여 행을 삽입하십시오.

3) PostgreSQL은 전체 텍스트 검색 을 수행합니다 . 스핑크스 엔진은 MySQL을 위해하는 것처럼 보입니다.


나는 최근에 들어 보았을 때 스핑크스를 확실히 볼 것입니다.
데릭 다우니

3

엔진을 하나만 사용하면 전체 서버 (메모리 구성, 캐시, 색인)를 최적화하는 것이 X 배 쉽습니다. 큰 데이터베이스에서 myisam과 innodb를 혼합하면 항상 엔진이 제대로 작동하기 위해 약간의 압박에 의해 강제로 고정됩니다 (그러나 우수하지는 않습니다 :)

sphinx , lucene ( solr )과 같은 일부 전용 텍스트 검색 엔진에 관심이 있고 데이터베이스 계층에서 제거하는 것이 좋습니다.

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