InnoDB 스토리지 엔진 B+ 트리의 트리 높이 도출

목차

1. 기본 결론: InnoDB 스토리지 엔진 B+ 트리의 트리 높이는 3~4개 레이어입니다.

2. 스토리지 엔진 B+ 트리 구조의 단순 분석

3. 기본키 인덱스 B+ 트리 유도

4. InnoDB 페이지의 내부 구조 도출

5. InnoDB 데이터 파일 도출 분석

6. B+ 트리 높이 도출 및 계산에 대한 일반적인 아이디어 요약

참고 자료, 서적 및 링크


1. 기본 결론: InnoDB 스토리지 엔진 B+ 트리의 트리 높이는 3~4개 레이어입니다.

InnoDB 스토리지 엔진의 B+ 트리의 트리 높이는 일반적으로 약 3-4 수준으로 상대적으로 작습니다. 이는 InnoDB 스토리지 엔진이 B+ 트리의 높이를 줄이기 위해 많은 최적화 전략을 사용하기 때문입니다. 여기에는 다음이 포함됩니다.

  1. 클러스터형 인덱스 : InnoDB 스토리지 엔진의 클러스터형 인덱스는 기본 키에 따라 구성되므로 비클러스터형 인덱스에 기본 키를 다시 저장하지 않아도 되므로 B+ 트리의 높이가 줄어듭니다.
  2. 페이지 분할 : B+ 트리의 페이지가 가득 차면 InnoDB 스토리지 엔진은 B+ 트리의 균형을 보장하기 위해 페이지를 분할합니다.
  3. 페이지 병합 : B+ 트리에서 일부 리프 노드의 공간 활용도가 낮을 ​​때 InnoDB 스토리지 엔진은 이러한 노드를 더 큰 노드로 병합하여 B+ 트리의 높이를 줄입니다.
  4. 적응형 해시 인덱스 : InnoDB 스토리지 엔진에서는 특정 테이블에 대한 특정 쿼리가 비클러스터형 인덱스를 자주 사용하는 경우 InnoDB가 자동으로 해당 인덱스에 대한 해시 인덱스를 생성하여 쿼리 효율성을 향상시킵니다.

이러한 최적화 전략을 사용하면 일반적으로 InnoDB 스토리지 엔진의 B+ 트리 높이를 더 작게 만들어 데이터베이스의 쿼리 효율성을 향상시킬 수 있습니다.

2. 스토리지 엔진 B+ 트리 구조의 단순 분석

InnoDB 스토리지 엔진에서는 인덱스와 데이터를 저장하고 구성하기 위해 B+ 트리 구조를 사용하며, 일반적인 인덱스 구성 테이블 구조는 다음과 같습니다.

이는 B+ 트리에 (id, name) 필드를 포함하는 데이터를 저장하는 방법입니다.

기본 키 ID와 다음 레벨 노드에 대한 포인터는 B+ 트리의 리프가 아닌 노드에 저장되고 실제 데이터는 리프 노드에 저장됩니다. 인접 노드는 리프 노드 사이에 이중 연결 리스트를 통해 연결됩니다.

여기서 "노드"는 InnoDB의 "페이지"입니다. "페이지"는 InnoDB가 데이터를 저장하는 가장 작은 단위이며, 기본 크기는 16K이다. "페이지"에 대한 이해는 다른 저장 모델로 확장될 수 있습니다. 예를 들어 파일 시스템과 디스크 모두 자체 최소 저장 단위가 있습니다. 파일 시스템의 최소 저장 단위는 4k인 반면 디스크의 최소 저장 단위는 4k입니다. 512바이트입니다. InnoDB는 다음과 같은 데이터 관계를 통해 디스크에서 데이터를 로드합니다.

InnoDB의 "페이지" 크기에서 우리는 다음을 추론할 수 있습니다: 테이블이 데이터를 저장하는지 여부에 관계없이 InnoDB에서는 최소 16K 공간을 차지합니다. 테이블이 아무리 크더라도 InnoDB에서 사용되는 공간은 정수 배수여야 합니다. 16 .

3. 기본키 인덱스 B+ 트리 유도

트리 높이 = 1인 경우: 이때 B+ 트리에는 리프 노드이기도 한 루트 노드라는 하나의 노드만 있고 모든 데이터는 이 노드에 저장됩니다. 단일 행 데이터 크기가 1k라고 가정합니다. 그런 다음 노드가 저장할 수 있는 데이터 행 수 = 노드 용량/단일 행 데이터 크기 = 16K/1K = 16개 데이터 행 .

트리 높이 = 2인 경우: 이렇게 B+ 트리에는 루트 노드와 리프 노드가 있으며 루트 노드에는 기본 키와 포인터가 있고 리프 노드에는 데이터가 저장됩니다.

각 리프 노드에 저장할 수 있는 데이터 행 수는 위와 같이 계산됩니다. = 노드 용량/단일 행 데이터 크기 = 16K/1K = 데이터 16행. 루트 노드에 저장할 수 있는 포인터 수 = 노드 용량 / (기본 키 길이 + 포인터 길이) = 16K / (8byte + 6byte) = 1170. (참고: 포인터 길이는 6바이트로 고정되어 있습니다. 기본 키는 bigint 유형을 사용하고 길이는 8바이트라고 가정합니다.)

따라서 트리 높이가 2인 B+ 트리의 경우 저장할 수 있는 데이터 행 수 = 단일 리프 노드에 저장된 데이터 행 수 X 루트 노드 포인터 수 = 16 X 1170 = 18720입니다.

트리 높이 = 3인 경우: 이때 B+ 트리에는 루트 노드, 리프가 아닌 노드 및 리프 노드가 포함됩니다.

위의 계산 방법에 따르면 트리 높이 = 3일 때 저장할 수 있는 행 수 = 단일 리프 노드에 저장된 데이터 행 수 X 비리프 노드 포인터 수 X 루트 노드 포인터 수 = 16

따라서 추론을 통해 다음과 같은 결론을 내릴 수 있습니다. 데이터의 단일 행 크기가 S 바이트이고 트리 높이가 H인 경우 bigint 유형 기본 키 B + 트리 인덱스에 저장할 수 있는 행 수 N은 동일합니다. 에게:

공식에 따라 계산됩니다. 트리 높이가 4일 때 2,000억 개 이상의 데이터 행을 저장할 수 있습니다. 이러한 종류의 데이터 용량은 대부분의 애플리케이션 요구 사항을 충족할 수 있으므로 대부분의 애플리케이션에서 B+ 트리 높이 3 또는 4가 데이터 스토리지 요구 사항을 충족할 수 있다고 말할 수 있습니다. B+ 트리의 높은 팬아웃과 낮은 트리 높이도 기본 키 쿼리 성능을 크게 향상시킵니다.

4. InnoDB 페이지의 내부 구조 도출

"페이지"의 공간은 사용자 데이터를 저장하는 데 사용된다고 가정하지만, 실제 "페이지"는 사용자 데이터를 저장하는 것 외에도 일부 보조 정보를 저장하는 공간도 예약합니다. 완전한 "페이지"는 다음 7개 부분으로 구성됩니다.

사용자 기록은 사용자 데이터 기록을 저장하는 데 사용되는 공간인 "페이지"에서 가장 많은 공간을 차지합니다 . Infimum + Supremum Records, Free Space, Page Directory에서 사용하는 아주 작은 공간을 무시한다면, 데이터 레코드를 저장하는데 사용되는 공간은 대략적으로 페이지 용량 - Fil Header - Page Header - Fil Trailer = 16384 - 38 이라고 생각됩니다. - 56 - 8 = 16282바이트. 이 결과를 바탕으로 수식을 업데이트합니다.

B+ 트리가 저장할 수 있는 데이터 행 수의 추론 및 계산을 통해 B+ 트리의 트리 높이가 일반적으로 1~4 레이어임을 측면에서 증명합니다 .

5. InnoDB 데이터 파일 도출 분석

위의 InnoDB 페이지 구조 분석을 통해 Page Header 부분에 전체 인덱스 트리에서 현재 페이지의 위치를 ​​나타내는 Page Level 필드가 있음을 알 수 있습니다.

  • 현재 페이지가 트리의 리프 노드에 있는 경우 페이지 수준=0
  • 현재 페이지가 리프 노드보다 한 수준 위에 있는 경우 페이지 수준=1
  • 비유하자면, 트리에 3개 수준이 있는 경우 리프 노드 페이지 수준=0, 리프가 아닌 노드 페이지 수준=1, 루트 노드 페이지 수준=2입니다.
  • Page Level을 통해 트리 높이를 유추하면 트리 높이 = 루트 노드의 Page Level + 1임을 알 수 있다.

따라서 기본키 인덱스에 있는 루트 노드의 Page Level 값을 InnoDB 데이터 파일에서 찾을 수 있다면 기본키 인덱스 트리의 트리 높이를 계산할 수 있다 .

InnoDB 데이터 파일에서 기본 키 인덱스의 페이지 번호를 찾습니다.

InnoDB 데이터 파일의 기본 키 인덱스 루트 노드를 구문 분석하려면 먼저 데이터 파일에서 기본 키 인덱스의 위치를 ​​찾아야 합니다. MySQL에 내장된 information_schema.INNODB_SYS_INDEXES와 information_schema.INNODB_SYS_TABLES에는 기본 키 인덱스가 위치한 페이지 번호에 대한 정보가 포함되어 있습니다.

SELECT
b.name as tableName, a.name as indexName, index_id, type, a.space, a.PAGE_NO
FROM
information_schema.INNODB_SYS_INDEXES a,
information_schema.INNODB_SYS_TABLES b
WHERE
a.table_id = b.table_id AND a.space <> 0 and b.name ='dbt3/lineitem' and a.name='PRIMARY';

이 SQL을 통해 쿼리된 lineitem 테이블의 기본 키 인덱스의 페이지 번호는 3입니다. 실제로 InnoDB의 모든 테이블의 기본키 인덱스 페이지 번호는 3인데, 이는 다른 테이블을 쿼리해 보면 확인할 수 있다.

데이터 파일에서 페이지 수준의 위치를 ​​계산합니다.

각 페이지의 크기(16K)를 통해 데이터 파일에서 기본 키 인덱스가 있는 페이지를 찾을 수 있습니다. 데이터 파일에서 페이지 수준 필드의 위치를 ​​추가로 찾으려면

InnoDB 페이지의 구조적 특성에 따르면 Fil Header 부분이 처음 38바이트를 차지하고, Page Level 필드가 Page Header 부분의 26바이트 오프셋에 위치하여 2바이트를 차지하는 것을 알 수 있다. 따라서 전체 페이지에서 Page Level 필드의 위치가 64바이트 오프셋의 위치라고 결론을 내릴 수 있다.

데이터 파일(lineitem.idb 파일)의 페이지 수준 필드를 구문 분석하려는 경우 건너뛰어야 하는 오프셋 = 3 * 16384(16K) + 38+ 26 = 49152+64=49216. 페이지 수준의 값은 오프셋의 다음 2바이트에 있습니다. lineitem.idb 파일의 Page Level=2, 즉 트리 height=Page Level+1=3 레이어가 파싱된 것을 볼 수 있습니다 .

6. B+ 트리 높이 도출 및 계산에 대한 일반적인 아이디어 요약

InnoDB 스토리지 엔진에서 B+ 트리를 사용할 때 B+ 트리의 높이는 일반적으로 다음 파생을 통해 계산할 수 있습니다.

  1. 먼저 B+ 트리의 노드 크기와 각 노드가 수용할 수 있는 인덱스 항목 수를 알아야 하는데, 이는 InnoDB 스토리지 엔진의 페이지 크기, 노드 헤더 크기, 인덱스 항목 크기와 같은 매개변수에 의해 결정될 수 있습니다.
  2. 그러면 B+ 트리의 정의에 따라 루트 노드, 중간 노드, 리프 노드의 최소 인덱스 항목 수를 계산할 수 있습니다. 일반적으로 루트 노드와 중간 노드에는 두 개 이상의 자식 노드가 있고 리프 노드에는 일반적으로 인덱스 항목 수가 가장 많습니다.
  3. 그러면 B+ 트리의 구조와 정의를 기반으로 루트 노드, 중간 노드, 리프 노드가 수용할 수 있는 최대 인덱스 항목 수를 계산할 수 있습니다. 중간 노드와 리프 노드의 경우 이 수는 노드 크기와 각 인덱스 항목의 크기에 따라 달라집니다.
  4. 마지막으로 B+ 트리의 정의와 인덱스 항목의 최소/최대 수를 사용하여 B+ 트리의 높이를 계산할 수 있습니다. InnoDB 스토리지 엔진에서는 일반적으로 쿼리 성능을 향상하고 디스크 IO 오버헤드를 줄이기 위해 B+ 트리의 높이를 최소값에 가깝게 유지하려고 합니다.

이는 B+ 트리의 높이를 계산하는 한 가지 방법일 뿐이라는 점에 유의해야 합니다. 서로 다른 스토리지 엔진과 데이터베이스는 서로 다른 최적화 전략을 사용할 수 있으므로 계산 결과가 다를 수 있습니다. 동시에, B+ 트리의 높이만이 쿼리 성능에 영향을 미치는 요소는 아니며, 인덱스 선택성, 데이터 분포 등의 요소도 고려해야 합니다.

참고 자료, 서적 및 링크

1. "MySQL 기술 인사이더: InnoDB 스토리지 엔진"(2판): MySQL 기술 인사이더(Douban)

2. 《InnoDB 내부: InnoDB 스토리지 엔진》: MySQL :: MySQL 8.0 참조 설명서 :: 15 InnoDB 스토리지 엔진

3. 《InnoDB: 최고의 가이드》: https://www.percona.com/blog/2018/06/05/innodb-the-ultimate-guide/

4. 《InnoDB 스토리지 엔진 내부》: https://mariadb.com/kb/en/innodb-storage-engine-internals/

5. InnoDB 데이터 페이지 구조

추천

출처blog.csdn.net/xiaofeng10330111/article/details/130464048