14 억 개의 레코드가있는 테이블이 있습니다. 테이블 구조는 다음과 같습니다.
CREATE TABLE text_page (
text VARCHAR(255),
page_id INT UNSIGNED
) ENGINE=MYISAM DEFAULT CHARSET=ascii
열에 대한 색인을 작성해야합니다 text
.
테이블 크기는 약 34G입니다.
다음 문장으로 색인을 만들려고했습니다.
ALTER TABLE text_page ADD KEY ix_text (text)
10 시간을 기다린 후에 마침내이 접근법을 포기했습니다.
이 문제에 대한 해결책이 있습니까?
UPDATE : 테이블을 업데이트하거나 삽입하거나 삭제할 수 없습니다. 컬럼에서 인덱스를 작성하는 이유 text
는 다음과 같은 종류의 SQL 쿼리가 자주 실행되기 때문입니다.
SELECT page_id FROM text_page WHERE text = ?
업데이트 : 테이블을 분할하여 문제를 해결했습니다.
테이블은 열에서 40 개로 분할됩니다 text
. 그런 다음 테이블에서 인덱스 작성을 완료하는 데 약 1 시간이 걸립니다.
테이블 크기가 매우 커지면 MySQL 인덱스 생성이 매우 느려집니다. 그리고 파티셔닝은 테이블을 더 작은 트렁크로 줄입니다.
답변
시스템이 작업에 달려 있지 않을 수 있습니까? MySQL (여기서는 SQL Server)을 사용하지 않지만 8 억 개의 엔트리 테이블을 인덱싱해야하는 어려움을 알고 있습니다. 기본적으로 …. 많은 빠른 디스크와 같이 적절한 하드웨어가 필요합니다. 나는 이제 거의 12 개의 Velociraptor를 사용하고 성능은 훌륭합니다.)
SQL Server (MS SQL Server가 아니라 SQL을 사용하는 데이터베이스 서버)는 디스크 액세스로 라이브 및 다이를 사용하며 일반 디스크는 더 큰 작업을 수행하지 않습니다.
답변
텍스트 필드의 첫 번째 (예 : 10) 문자에 대한 인덱스를 만들 수 있습니다.
문서에서 :
col_name (length) 구문을 사용하여 인덱스 접두사 길이를 지정하여 열 값의 앞 부분 만 사용하는 인덱스를 만들 수 있습니다.
CREATE INDEX ix_text ON text_page (text(10))
답변
테이블을 분할하여 문제를 해결했습니다.
테이블은 열에서 40 개로 분할됩니다 text
. 그런 다음 테이블에서 인덱스 작성을 완료하는 데 약 1 시간이 걸립니다.
테이블 크기가 매우 커지면 MySQL 인덱스 생성이 매우 느려집니다. 그리고 파티셔닝은 테이블을 더 작은 트렁크로 줄입니다.
답변
sort_buffer_size를 4GB로 설정하십시오 (또는 보유하고있는 메모리 용량에 따라 많이 할 수 있습니다).
지금 create 인덱스는 정렬을 수행하지만 32MB sort_buffer_size가 있으므로 기본적으로 하드 드라이브를 불필요하게 스 래싱합니다.
답변
다음과 같이 쿼리 할 필요가없는 경우 :
SELECT page_id FROM text_page WHERE text LIKE '?%';
새 해시 열을 만들고 열을 기준으로 테이블을 인덱싱하는 것이 좋습니다. 테이블 + 인덱스의 전체 크기는 훨씬 작을 수 있습니다.
UPD : 그런데 14 억 개의 1 차 키 정수는 약 6GB를 차지합니다. 즉, 문자열의 평균 길이는 30 자 미만입니다.
MERGE 스토리지 엔진도 살펴 봐야 합니다.
답변
이를 수행하는 한 가지 방법은 인덱스 세트로 새 테이블을 작성하고 데이터를 새 테이블에 복사하는 것입니다.
또한 충분한 임시 공간이 있는지 확인하십시오.
답변
여전히 최선을 다하는 방법이 궁금하다면 온라인 alter table 도구를 사용하는 것이 좋습니다.
인터넷에는 많은 것들이 있으며 유명한 것들 중 하나는 다음과 같습니다.
- Percona 온라인 스키마 변경 (이것을 사용합니다)
http://www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html - Facebook OSC, 다운로드 할 수있는 URL을 찾을 수 없습니다
우리는 큰 테이블 (500mil 이상의 레코드)과 동일한 문제가 있으며 변경이 완벽합니다. 새 tmp 테이블을 작성하고, 원래 테이블에 트리거를 추가하고 (새 업데이트 / 삭제 / 삽입 레코드에 대해) 그 동안 모든 레코드를 새 테이블에 새 구조로 복사합니다.
행운을 빕니다!