이 글에서는 인덱스 구조와 관련된 이슈를 주로 소개하는 mysql 관련 지식을 소개합니다. 그렇다면 인덱스의 구조는 무엇일까요? 인덱싱이 왜 그렇게 빠를 수 있나요? 아래 내용을 살펴보겠습니다. 모두에게 도움이 되기를 바랍니다.
추천 학습: mysql 튜토리얼
우선, 지속성을 달성하려면 인덱스를 통해 쿼리할 때만 인덱스를 하드 디스크에 저장할 수 있다는 점을 알아야 합니다. , 하드디스크에서는 I/O 작업이 발생하므로 인덱스를 설계할 때는 검색 횟수를 최대한 줄여 I/O 시간을 줄여야 합니다.
또한 매우 중요한 원칙을 알아야 합니다. 데이터베이스 관리 저장 공간의 기본 단위는 페이지(Page)
이며, 여러 행의 레코드(Row)가 한 페이지에 저장됩니다. 页(Page)
,一个页中存储多条行记录(Row)。
计算机系统对磁盘 I/O 会做预读
优化,当一次I/O时,除了当前磁盘地址的数据以外,还会把相邻的数据也读取到内存缓冲池中,每一次 I/O 读取的数据成为一页,InnoDB 默认的页大小是 16KB。
连续的 64 个页组成一个区(Extent)
,一个或多个区组成一个段(Segment)
,一个或多个段组成表空间(Tablespace)
。InnoDB 有两种表空间类型,共享表空间表示多张表共享一个表空间,独立表空间表示每张表的数据和索引全部存在独立的表空间中。
数据页结构如下(图源:极客时间《MySQL 必知必会》):
数据页的 7 个结构内容可以大致分为以下三类:
详情可参考淘宝的数据库内核月报
很自然的,我们会想到查找算法中涉及到的一些常用数据结构,比如二叉查找树,二叉平衡树等等,实际上,Innodb 的索引是用 B+ 树
미리 읽기
최적화를 수행합니다. I/O가 수행되면 현재 디스크 주소의 데이터 외에도 인접한 데이터도 디스크로 읽혀집니다. 메모리 버퍼 풀에서는 각 I/O가 읽는 데이터가 1페이지가 되며 InnoDB의 기본 페이지 크기는 16KB입니다. 익스텐트
, 하나 이상의 익스텐트는 세그먼트
를 형성하고, 하나 이상의 세그먼트는 테이블스페이스
를 형성합니다. InnoDB에는 두 가지 테이블스페이스 유형이 있습니다. 공유 테이블스페이스는 여러 테이블이 하나의 테이블스페이스를 공유한다는 의미입니다. 독립 테이블스페이스는 각 테이블의 데이터와 인덱스가 모두 독립된 테이블스페이스에 저장된다는 의미입니다. 데이터 페이지의 구조는 다음과 같습니다(출처: Geek Time "Must Know MySQL"):
데이터 페이지의 7개 구조적 내용은 대략 다음 세 가지 범주로 나눌 수 있습니다.
당연히 우리는 생각할 것입니다 이진 검색 트리, 이진 균형 트리 등과 같은 검색 알고리즘과 관련된 몇 가지 일반적인 데이터 구조입니다. 실제로 Innodb의 인덱스는 B+ 트리를 사용하여 달성합니다. 이 인덱스 구조가 왜 선택되었습니다.
먼저 이진 검색 트리의 정의를 간단히 살펴보겠습니다. 이진 검색 트리에서 찾으려는 키가 루트 노드보다 크면 올바른 하위 트리에서 검색합니다. 루트 노드보다 작다면, 키를 찾을 때까지 왼쪽 하위 트리에서 검색하세요. 시간 복잡도는 O(logn)입니다. 예를 들어, 시퀀스 [4,2,6,1,3,5,7]은 다음과 같은 이진 검색 트리를 생성합니다.
그러나 일부 특별한 경우에는 이진 트리의 깊이가 매우 커집니다. [1,2,3,4,5,6,7]과 같이 다음과 같은 트리가 생성됩니다.
k - 1
个关键字 和 k
자식 노드에 대한 포인터가 포함됩니다. 위에서 언급했듯이 각 I/O는 한 페이지 크기의 디스크 블록의 데이터를 미리 읽습니다. 디스크 블록의 내용은 I/O의 구조를 나타내는 데 사용됩니다. tree는 다음과 같습니다(출처: Ji 게스트 타임에 SQL을 알아야 합니다):
B-tree도 정렬됩니다. 자식 노드 포인터는 키워드보다 1이 더 많아야 하므로 키워드를 사용하여 세그먼트를 나눌 수 있습니다. 그림의 예에서와 같이 각 A 노드에는 디스크 블록 2와 같이 2개의 키워드와 3개의 하위 노드가 있습니다. 첫 번째 바이트 포인트의 키워드 3, 5는 자신의 첫 번째 하위 노드 8보다 작습니다. 두 번째 자식 노드의 9, 10은 8과 10 사이입니다. 12와 12 사이에서 세 번째 자식 노드의 값은 13과 15로 두 번째 자식 노드 12보다 큽니다.
지금 9를 찾고 싶다고 가정하면 단계는 다음과 같습니다.
이 발견되었습니다. 많은 비교 작업이 이루어졌지만 사전 읽기로 인해 디스크 블록 내 비교가 메모리에서 수행되므로 디스크 I/O를 소비하지 않습니다. 위 작업에는 3개의 I/O만 필요합니다. Os는 이상적인 구조입니다.
B+ 트리는 B 트리를 기반으로 더욱 개선되었습니다. B+ 트리와 B 트리의 차이점은 다음과 같습니다.
예제는 다음과 같습니다. 이 예에서는 상위 노드의 키워드가 모두 하위 노드 간의 최소값입니다(출처: Geek Time SQL이 알아야 함).
키워드를 찾고 싶다고 가정합니다. 16에서 검색 단계는 다음과 같습니다.
B+ 트리 장점:
MySQL의 메모리 저장 엔진의 기본 인덱스 구조는 해시 인덱스입니다. 특정 알고리즘(예: MD5, SHA1, SHA2 등)을 사용하여 임의 길이의 입력을 고정 길이의 출력으로 변환하는 해시 함수라는 함수입니다. 해시 함수에 대한 자세한 소개는 Baidu Encyclopedia를 참조하세요.
해시 검색 효율성은 O(1)로 매우 효율적입니다. Python의 dict, golang의 맵 및 Java의 해시 맵은 모두 Redis와 같은 Key-Value 데이터베이스도 Hash로 구현됩니다.
정확한 검색을 위해서는 B+ 트리 인덱스보다 해시 인덱스가 더 효율적이지만, 해시 인덱스에는 몇 가지 한계가 있어 가장 주류 인덱스 구조는 아닙니다.
위의 이유로 Mysql InnoDB 엔진은 Hash 인덱스를 지원하지 않지만 메모리 구조에 Adaptive Hash index 기능이 있습니다. 특정 인덱스 값이 매우 자주 사용되는 경우 B+ 트리를 기반으로 합니다. index 해시 인덱스를 자동으로 생성하여 쿼리 성능을 향상시킵니다.
적응형 해시 인덱스는 해시 인덱스를 사용하여 B+ 트리 인덱스에 페이지 주소를 저장하고 해당 리프 노드를 빠르게 찾는 "인덱스 인덱스"로 이해될 수 있습니다. innodb_adaptive_hash_index
변수를 통해 보실 수 있습니다.
추천 학습: mysql 튜토리얼
위 내용은 MySQL 인덱스 구조에 대한 심층적인 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!