큰 mysql 테이블에 인덱스 추가


13

나는 테이블이있다

| base_schedule_line_items | CREATE TABLE base_schedule_line_items(
idint (10) unsigned NOT NULL AUTO_INCREMENT,
installmentint (10) unsigned NOT NULL,
on_datedate NOT NULL,
actual_datedate DEFAULT NULL,
payment_typeint (11) NOT NULL,
scheduled_principal_outstandingdecimal (65,0) NOT NULL,
scheduled_principal_duedecimal (65,0) NOT NULL,
scheduled_interest_outstandingdecimal (65,0) NOT NULL,
scheduled_interest_duedecimal (65,0) NOT NULL,
currencyint (11) NOT NULL,
updated_atdatetime NOT NULL DEFAULT '2013-01-06 14:29:16',
created_atdatetime NOT NULL DEFAULT ' 2013-01-06 14:29:16 ',
loan_base_schedule_idint (10) unsigned NOT NULL,
lending_idint (10) unsigned NOT NULL,
rescheduletinyint (1) DEFAULT'0 ',
PRIMARY KEY ( id),
KEY index_base_schedule_line_items_loan_base_schedule ( loan_base_schedule_id), KEY index_bslt_spd( scheduled_principal_due),
index_bslt_lending(lending_id)
KEY index_bslt_actualdate( actual_date)
KEY index_bslt_spsila ( loan_base_schedule_id, scheduled_principal_due, scheduled_interest_due, actual_date)
KEY index_bslt_ondate( on_date)
KEY index_bslt_oa( on_date, actual_date)
KEY index_bslt_ol( on_date, loan_base_schedule_id)
KEY index_bslt_oli( on_date, lending_id)
) ENGINE = 이노 AUTO_INCREMENT = 30,410,126 DEFAULT CHARSET = UTF8 |

이제이 테이블에 3 천만 개의 레코드가 있으므로 여기에 두 개의 인덱스를 추가해야하며 추가하는 데 몇 년이 걸리는 것처럼 보입니다.

base_schedule_line_items 테이블을 변경 인덱스 추가 index_bslt_sla (scheduled_principal_due, actual_date, lending_id);
alter table base_schedule_line_items 인덱스 추가 인덱스 index_bslt_ssla (scheduled_principal_due, scheduled_interest_due, lending_id, actual_date);

아래 언급 된 쿼리를 사용하여 테이블 크기를 확인했습니다.

SELECT table_name AS "Tables", round ((((data_length + index_length) / 1024/1024), 2) "MB 크기"from information_schema.TABLES WHERE table_schema = "my_database_name";

결과는

base_schedule_line_items | 20111.00

나는 이것을 사용하여 데이터 길이를 계산하고 인덱스 길이를 생략했습니다.

SELECT table_name AS "Tables", round ((((data_length) / 1024 / 1024), 2) "MB 크기"FROM information_schema.TABLES WHERE table_schema = "my_database_name";

결과는

base_schedule_line_items | 9497.00

인덱스

KEY index_bslt_actualdate (actual_date)
KEY의 index_bslt_spsila (loan_base_schedule_id, scheduled_principal_due, scheduled_interest_due, actual_date)
KEY의 index_bslt_ondate (ON_DATE)
KEY의 index_bslt_oa (ON_DATE, actual_date)
KEY의 index_bslt_ol (ON_DATE, loan_base_schedule_id)
KEY의 index_bslt_oli (ON_DATE, lending_id)

나에 의해 추가되었지만, 나는 확실하지 않거나 다른 지수가 어떤 목적으로 추가 되었는가. 이것은 상당히 큰 응용 프로그램입니다. 이제 select 문을 사용하여 보고서를 추출하는 데 도움이되는 위에서 언급 한 두 개의 인덱스를 추가해야하며 추가하기가 매우 어렵습니다. 어떤 도움이라도 대단히 감사하겠습니다.

답변:


16

큰 테이블을 변경하는 활동은 단계적으로 수행됩니다.

  1. 테스트 DB에서 필요한 필드와 색인으로 새 테이블 만들기 (구조 만)
  2. 기존 테이블에서 데이터를 덤프하고 테스트 DB에서 새로 작성된 테이블에 동일한 데이터를로드하십시오.
  3. 이제 가동 중지 시간을 발표하십시오. :)
  4. 이름을 바꾸어 테이블을 교환하십시오- RENAME table ur_db.table_name to test.temp, test.table_name to ur_db.table_name, test.temp to test.table_name;이것은 1 초의 짧은 시간에 원자 작업입니다.
  5. 추가 레코드를 새로 작성된 테이블 (덤프 후로드 한 레코드)에로드하십시오. 이 단계는 3 단계 전에 수행 할 수도 있습니다. 또한 다운 타임을 줄입니다.
  6. 그리고 당신의 시스템은 돌아 왔습니다

몇 가지 참고 사항 :

  1. 이와 같이 정보 스키마를 직접 누르지 않아도됩니다. SHOW TABLE STATUS from db like 'table_name'
  2. alter table의 속도는 I / O 속도와 다소 관련이 있습니다. 우리가 직접 위의 단계없이 직접 변경 테이블을 실행했을 때, 우리는 40GB + 테이블 크기가 약 4 시간이 걸렸습니다. 20GB 데이터가 몇 년이 걸리면 오래된 시스템을 사용하는 것입니다.
  3. 또한 index_bslt_ondate, index_base_schedule_line_items_loan_base_schedule다른 인덱스와 같이 원치 않는 인덱스를 삭제하면 가장 왼쪽 열이 인덱스 열로 표시됩니다.

이 단계 중 어느 것에 대해서도 설명이 필요하면 알려주십시오.

편집 : 프로세스를 자동화하는 간단한 파이썬 스크립트 https://github.com/georgecj11/hotswap_mysql_table.git


10

pt-online-schema-change 와 같은 도구를 사용 하여 애플리케이션을 차단하지 않고 색인을 추가 할 수 있습니다. 기본 논리는 다음과 같습니다.

  • 새 인덱스로 테이블의 빈 복사본을 만듭니다.
  • 기존 테이블에 트리거를 추가하여 테이블에 도달 한 모든 변경 사항이 테이블 사본에 적용되도록합니다. *
  • 이전 테이블에서 새 테이블로 행 복사를 시작하십시오.
  • 복사가 완료되면 테이블을 교체하십시오
  • 이전 테이블을 삭제

* 테이블에 기존 트리거가 있으면 도구가 작동하지 않습니다

교환 및 낙하 동작은 공구에 전달 된 옵션에 따라 조정할 수 있습니다.

또한 외래 키에 문제가 있으므로 도구 설명서를 읽고 해당 기능을 완전히 이해하십시오.

물론 필요한 경우 복원 할 수 있도록 테이블 백업이 있는지 확인하는 것이 좋습니다.

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