MySQL 인덱스 유지 관리


12

조각화를 방지하고 일부 쿼리 실행을 최적화하기 위해 MySQL에서 인덱스를 유지 관리하는 방법에 대해 많은 연구를했습니다.

테이블에 사용 가능한 최대 공간과 데이터 및 인덱스에 사용되는 공간 간의 비율을 계산하는 수식에 익숙합니다.

그러나 내 주요 질문에 여전히 답이 없습니다. 아마도 이것은 SQL Server의 인덱스 유지 관리에 익숙하기 때문에 MySQL에서 다소 비슷해야한다고 생각하는 경향이 있습니다.

SQL Server에서 여러 인덱스를 가질 수 있으며 각 인덱스는 서로 다른 조각화 수준을 가질 수 있습니다. 그런 다음 나머지 하나에 영향을주지 않고 특정 인덱스에서 하나를 선택하여 'REORGANIZE'또는 'REBUILD'작업을 수행 할 수 있습니다.

내가 아는 한, '테이블 조각화'는 없으며 SQL Server는 '테이블 조각화'를 수정하는 도구를 제공하지 않습니다. 그것이 제공하는 것은 내부 및 외부 조각화뿐만 아니라 색인 조각화 (인덱스에 의해 사용 된 페이지 수 대 전체 및 연속성 간의 비율과 같은 것으로 이해 됨)를 검사하는 도구입니다.

그 모든 것은 적어도 저에게는 이해하기 매우 간단합니다.

이제 MySQL에서 인덱스를 유지 관리해야 할 때 위에서 언급 한 것처럼 '테이블 조각화'라는 개념 만 존재합니다.

MySQL의 테이블에는 여러 개의 인덱스가있을 수 있지만 유명한 수식으로 '조각화 비율'을 확인하면 각 인덱스의 조각화가 아니라 테이블 전체가 표시됩니다.

MySQL에서 인덱스를 최적화하려면 SQL Server에서와 같이 작동 할 특정 인덱스를 선택하지 않습니다. 대신 전체 테이블에서 'OPTIMIZE'작업을 수행하는데, 이는 아마도 모든 인덱스에 영향을 줄 것입니다.

테이블이 MySQL에서 최적화되면 데이터 + 인덱스에 사용 된 공간과 전체 공간의 비율이 줄어들어 하드 드라이브의 물리적 재구성이 물리적 공간이 줄어든다는 것을 의미합니다. 그러나 인덱스 조각화는 실제 공간뿐만 아니라 삽입 및 업데이트로 인해 시간이 지남에 따라 변경된 트리의 구조입니다.

마지막으로 InnoDB / MySQL에 테이블이 있습니다. 이 테이블에는 3 백만 개의 레코드, 105 개의 열 및 55 개의 인덱스가 있습니다. 인덱스는 2.1GB 인 1.5GB입니다.

이 테이블은 업데이트, 삽입 (실제로 레코드를 삭제하지는 않음)으로 인해 매일 수천 번 사용되었습니다.

이 테이블은 수년에 걸쳐 만들어졌으며 아무도 인덱스를 유지 관리하지 않는다는 것을 알고 있습니다.

나는 거기에서 거대한 조각화를 찾을 것으로 기대했지만 처방 된 조각화 계산을 수행 할 때

free_space / (data_length + index_length)

0.2 %의 조각화 만 있음이 밝혀졌습니다. IMHO는 매우 비현실적입니다.

따라서 큰 질문은 다음과 같습니다.

  1. 전체 테이블이 아닌 MySQL에서 특정 인덱스의 조각화를 확인하는 방법
  2. OPTIMIZE TABLE은 실제로 SQL Server에서와 같이 인덱스의 내부 / 외부 조각화를 수정합니까?
  3. MySQL에서 테이블을 최적화하면 실제로 테이블의 모든 인덱스를 다시 작성합니까?
  4. 트리 자체를 다시 만들지 않고 인덱스의 실제 공간을 줄이는 것이 실제로 더 나은 성능으로 해석된다고 생각하는 것이 현실적입니까?

최적화 테이블은 확실히 innodb에서 클러스터 된 인덱스를 정리합니다

1
프로그래밍 문제가 아닌 훌륭한 질문입니다. 그것이 속한 곳으로 이동합니다 :>

답변:


6

인덱스 조각화가 과대 평가되었습니다. 그것에 대해 걱정하지 마십시오.

InnoDB는 두 개의 인접한 빈 블록을 자연 처리로 병합합니다.

BTree에 대한 임의의 조치로 인해 평균 69 %가 가득 찼습니다. 물론 이것은 100 %는 아니지만 "고정"의 오버 헤드는 그만한 가치가 없습니다.

SHOW TABLE STATUS "Data_free"에는 특정 "free"공간이 포함되지만 다른 "free"공간은 포함되지 않습니다.

각 블록에는 사용되지 않은 공간이 있습니다. 무료 16KB 블록; 무료 "extents"(nMB 청크); MVCC 행은 수확 대기 중입니다. 비 리프 노드에는 자체 조각화가 있습니다. 기타

Percona와 Oracle은 인덱스의 크기 (블록 수)를 보는 방법이 다릅니다. 나는 "자유"라는 제한적인 정의 때문에 그들 중 어느 것도 유용하지 않다고 생각합니다. 블록 (각 16KB)이 청크 (몇 MB)로 할당되어 모든 종류의 조각화가 있다고 생각합니다. 실제로는 일반적으로 이러한 다중 MB 청크 중 하나 일뿐입니다. 그리고 OPTIMIZE TABLE공간을 반드시 회수 할 필요는 없습니다.

SQL Server가 BTree를 사용하는 경우 "조각화가 없다"고 말합니다. "블록 분할"에서 어떤 일이 발생하는지 생각해보십시오. 또는 지속적으로 조각 모음의 오버 헤드를 생각하십시오. 어느 쪽이든 당신은 잃습니다.

또한 테이블과 인덱스는 본질적으로 동일한 구조입니다.

  • 일부 인덱스를 기반으로하는 B + Tree
  • "데이터"는 기본 키를 기반으로합니다. 각 보조 인덱스는 해당 인덱스를 기반으로하는 B + Tree입니다.
  • "데이터"의 리프 노드는 테이블의 모든 열을 포함합니다.
  • 보조 인덱스의 리프 노드에는 해당 보조 인덱스의 열과 PRIMARY KEY의 열이 포함됩니다.

이있는 경우 파일 크기 innodb_file_per_table = ON를 확인하여 OPTIMIZE TABLE 후 축소 (있는 경우)를 명확하게 볼 수 있습니다 .ibd. 의 경우 OFF정보가에 묻혀 ibdata1있지만 SHOW TABLE STATUS모든 "사용 가능한"공간이 모든 테이블에 속하기 때문에 상당히 정확할 수 있습니다. 미리 할당 된 청크를 제외하고는

새로 최적화 된 테이블 당 파일 테이블의 Data_free는 정확히 4M, 5M, 6M 또는 7M입니다. 다시 말하지만 이것은 사전 할당이며 세부 정보를 제공하지 못한 것입니다.

저는 InnoDB와 함께 10 년 이상 일했습니다. 나는 크고 작은 수천 개의 다른 테이블로 작업했습니다. 나는 천에서 하나의 테이블 만이 실제로 필요하다고 말합니다 OPTIMIZE TABLE. 다른 테이블에서 사용하면 낭비입니다.

105 개의 열은 많지만 너무 많지는 않습니다.

테이블 에 55 개의 인덱스가 있습니까? 그건 나빠. 이는 한 번에 55 개의 업데이트입니다 INSERT. 더 논의하겠습니다. INDEX(a)당신도 가지고 있다면 쓸모가 없다는 것을 명심하십시오 INDEX(a,b). 그리고 INDEX(flag)때문에 낮은 기수의 쓸모가 없다. (그러나 INDEX(flag, foo)유용 할 수 있습니다.)

Q1 : 데이터 또는 보조 인덱스에서 모든 형태의 조각화를 확인할 수있는 좋은 방법이 없습니다.

Q2, Q3 : 새 테이블과 모든 행으로 OPTIMIZE TABLE테이블을 재구성 한 다음 및 . 상기 PK 것을 보증한다 순서의 데이터 재 - 삽입 된 데이터는 잘 조각 모음이다. 지수는 또 다른 문제입니다.CREATEingINSERTingRENAMEingDROPping

Q4 : 당신은 DROPreCREATE각 인덱스를 정리합니다. 그러나 이것은 매우 느린 과정입니다. 5.6에는 약간의 속도 향상이 있지만 조각 모음에 도움이되는지 모르겠습니다.

그런 ALTER TABLE ... DISABLE KEYS다음 ENABLE그들 도 가능 합니다. 이를 통해 모든 보조 인덱스를 한 번에보다 효율적으로 재구성 할 수 있습니다 .


Rick, 파일이 아닌 '105'필드를 의미
Nicolas

1

전체 테이블이 아닌 MySQL에서 특정 인덱스의 조각화를 확인하는 방법

통과하다.

OPTIMIZE TABLE은 실제로 SQL Server에서와 같이 인덱스의 내부 / 외부 조각화를 수정합니까?

테이블과 인덱스를 완전히 다시 작성합니다.

MySQL에서 테이블을 최적화하면 실제로 테이블의 모든 인덱스를 다시 작성합니까?

그것은 같은 대답을 가진 같은 질문입니다.

트리 자체를 다시 만들지 않고 인덱스의 실제 공간을 줄이는 것이 실제로 더 나은 성능으로 해석된다고 생각하는 것이 현실적입니까?

나무 재건 하지 않고 공간 줄일 수 있다고 생각하는 것은 현실적이지 않습니다 . 그들은 함께 간다.


# 1에 대한 답 : 그것은 정확하지는 않지만 열에 SHOW TABLE STATUS LIKE 'mytable'힌트를 줄 것 data free입니다. dev.mysql.com/doc/refman/5.6/en/show-table-status.html
뽑아 낸 Keriaki에게

알아요,하지만 여전히 특정 인덱스의 공간이 없습니다
Nicolas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.