SQL INDEX-작동 방식


19

데이터베이스SQL에 대한 나의 지식은 대부분 대학 수업을 기반으로합니다. 어쨌든, 나는 데이터베이스 작업을하고있는 회사에서 거의 1 년에 한 번의 몽타주를 보냈습니다.

나는 몇 권의 책을 읽고 난 같은 데이터베이스에 대한 몇 가지 교육에 참여를 촬영 한 MySQL, PostgreSQL, SQLite, Oracle또한 몇 가지 nonSQL db우리의 등 MongoDB, Redis, ElasticSearch

내가 말했듯이, 나는 많은 지식이 부족한 채로 구걸을했지만 오늘날 누군가는 내 구걸 자의 지식에 완전히 반대하는 것을 말했습니다.

설명하겠습니다. SQL 데이터베이스를 가져 와서 Person내부에 레코드가 거의없는 간단한 테이블 을 만듭니다 .

id | name   | age
-----------------
1  | Alex   | 24
2  | Brad   | 34
3  | Chris  | 29
4  | David  | 28
5  | Eric   | 18
6  | Fred   | 42
7  | Greg   | 65
8  | Hubert | 53
9  | Irvin  | 17
10 | John   | 19
11 | Karl   | 23

지금, 그것은 부분입니다, 나는 집중하고 싶습니다- id입니다 INDEX.

지금까지는 이런 식으로 작동한다고 생각했습니다. 테이블을 만들 때 INDEX비어 있습니다. 테이블에 새 레코드를 추가 할 때 INDEX일부 alghortims를 기반으로 다시 계산됩니다. 예를 들면 다음과 같습니다.

하나씩 그룹화 :

1    ... N
N+1  ... 2N
     ...
XN+1 ... (X+1)N

그래서, 내 예를 들어 size = 11 elements그리고 N = 3그것은 다음과 같이 될 것입니다 :

id | name   | age
-----------------
1  | Alex   | 24     // group0
2  | Brad   | 34     // group0
3  | Chris  | 29     // group0
4  | David  | 28     // group1
5  | Eric   | 18     // group1
6  | Fred   | 42     // group1
7  | Greg   | 65     // group2
8  | Hubert | 53     // group2
9  | Irvin  | 17     // group2
10 | John   | 19     // group3
11 | Karl   | 23     // group3

따라서 쿼리를 사용할 때 SELECT * FROM Person WHERE id = 8간단한 계산을 수행 하므로이 8 / 3 = 2객체를 찾아야 group2하면이 행이 반환됩니다.

8  | Hubert | 53

여기에 이미지 설명을 입력하십시오

이 방법은 시간에 작동하는 O(k)k << size. 물론 행을 그룹으로 구성하는 alghoriTM은 훨씬 더 복잡하지만이 간단한 예는 내 관점을 보여줍니다.

이제 저는 오늘 보여 드린 또 다른 접근법을 제시하고 싶습니다.

이 테이블을 다시 한 번 살펴 보겠습니다.

id | name   | age
-----------------
1  | Alex   | 24
2  | Brad   | 34
3  | Chris  | 29
4  | David  | 28
5  | Eric   | 18
6  | Fred   | 42
7  | Greg   | 65
8  | Hubert | 53
9  | Irvin  | 17
10 | John   | 19
11 | Karl   | 23

이제, 우리는 비슷한을 만드는 Hashmap매핑 (사실, 말 그대로 그것은 해시지도입니다) idaddress이 ID를 가진 행의는. 의 말을하자:

id | addr 
---------
1  | @0001
2  | @0010
3  | @0011
4  | @0100
5  | @0101
6  | @0110
7  | @0111
8  | @1000
9  | @1001
10 | @1010
11 | @1011

이제 쿼리를 실행할 때 : SELECT * FROM Person WHERE id = 8

id = 8메모리의 주소에 직접 매핑 되고 행이 반환됩니다. 물론 이것의 복잡성은입니다 O(1).

이제 질문이 거의 없습니다.

1. 두 솔루션의 장점과 단점은 무엇입니까?

2. 현재 데이터베이스 구현에서 어느 것이 더 인기가 있습니까? 다른 DB가 다른 접근법을 사용하고 있습니까?

3. 비 SQL DB에 존재합니까?

미리 감사합니다


비교

               |      B-tree     |   Hash Table
----------------------------------------------------
----------------   one element   -------------------
----------------------------------------------------
SEARCHING      |  O(log(N))      | O(1) -> O(N)  
DELETING       |  O(log(N))      | O(1) -> O(N)
INSERTING      |  O(log(N))      | O(1) -> O(N)
SPACE          |  O(N)           | O(N)
----------------------------------------------------
----------------    k elements   -------------------
----------------------------------------------------
SEARCHING      |  k + O(log(N))  | k * O(1) -> k * O(N)
DELETING       |  k + O(log(N))  | k * O(1) -> k * O(N)
INSERTING      |  k + O(log(N))  | k * O(1) -> k * O(N)
SPACE          |  O(N)           | O(N)

N-레코드 수

내가 맞아? 각 삽입 / 삭제B-tree해시 테이블 을 다시 작성하는 비용은 어떻습니까? 의 경우 B-트리 우리는 몇 가지 포인터를 변경해야하지만, 경우에 균형 B- 트리 가 더 많은 노력이 필요합니다. 또한 해시 테이블의 경우 특히 작업이 충돌을 일으키는 경우 작업을 거의하지 않아도됩니다 .


2
두 번째 방법에서는 해시 인덱스를 설명합니다. O(1)당신 에 관한 부분 이 맞았습니다! 첫 번째 방법으로, 당신은 B- 트리 인덱스를 설명하는 것 같지만 약간의 오해가 있습니다. 그것은 나무가 더 수준 (그것이 큰, 작은, 작은 가지, ..., 다음 잎 :이, 나무의이 같은 더 복잡하다 (3 또는 아무것도으로 나누기)에는 계산이 없다
ypercubeᵀᴹ

3
BTrees : en.m.wikipedia.org/wiki/B-tree 여러분의 대학에 이것을 설명하는 알고리즘 코스가 없다는 것에 놀랐습니다
Philᵀᴹ

@ ypercube 안녕하세요, 답변 주셔서 감사합니다. 물론 다음과 같이 썼습니다 : Of course, an alghoritm to organise rows in groups is for sure much more complicated but I think this simple example shows my point of view.물론, 훨씬 더 복잡하다는 것을 알고 있습니다. 마지막으로 코드에서 말할 때 INDEX내 솔루션 ( 1 또는 2 ) 중 어느 것이이 실제 솔루션 에 더 가깝습니까? 에 따라 레코드에 액세스하는 데 필요한 시간은 어떻습니까 INDEX. 정말 O(1)입니까? B-tree 인덱스를 사용하면 소리가 매우 비슷 O(log2(N))합니다. 내가 맞아?
ruhungry

@FreshPhilOfSO 나는 그것에 대해 약간의 강의라고 생각합니다. 아마, 나는 뭔가를 놓쳤다.
ruhungry

ElasticSearch는 B-나무에 비해 완전히 다른 반전 인덱스를 사용 elastic.co/blog/found-elasticsearch-from-the-bottom-up
루이스 마르티네스

답변:


12

기본적으로 B- 트리 인덱스와 해시 인덱스를 설명하고 있습니다. 둘 다 장소가 있지만 둘 다 다른 직업에 가장 적합합니다.

장점과 단점

B- 트리 (및 B +-트리) 인덱스는 일반적으로 균형이 조정됩니다. 이것은 값을 찾는 것이 트리의 어느 위치에 있든 항상 같은 시간이 걸린다는 것을 의미합니다 (O (log n)). 일반적으로 트리의 레벨 수는 제한되어 있으므로 "더 깊이"가 아니라 "더 넓게"나타나는 경향이 있습니다. 그러나 작은 데이터 세트의 경우 B- 트리를 유지 관리하고 사용하는 비용은 모든 행을 읽는 것 이상일 수 있습니다. B- 트리 인덱스는 큰 데이터 세트, 선택성이 낮은 데이터 세트 또는 하나의 객체가 아닌 다양한 객체를 선택하려는 데이터 세트에 적합합니다.

해시 테이블은 소규모 데이터 세트에 적합합니다. 해시 인덱스에는 사용 된 해싱 알고리즘에 따라 미리 정의 된 수의 해시 버킷이 있습니다. 이는 주어진 해시 알고리즘이 너무 많은 고유 한 해시를 생성 할 수 있기 때문에 "더 넓지"않고 "더 깊은"것만 가져옵니다. 데이터베이스 엔진이 올바른 버킷을 찾으면 해당 버킷의 모든 객체를 탐색하여 원하는 버킷을 찾습니다. 작고 선택적인 데이터 세트를 사용하면 각 버킷에 매우 적은 수의 객체가 포함되어 있으며 매우 빠르게 해결됩니다. 더 큰 데이터 세트를 사용하면 버킷이 훨씬 더 혼잡 해집니다. 따라서 필요한 객체가 작은 버킷에 있거나 버킷의 시작 부분에 가까우면 매우 빠르게 반환됩니다. 큰 버킷의 끝에 있으면 시간이 더 오래 걸립니다. 지수의 균형이 맞지 않으므로 성능은 O (1)에서 O (n)까지입니다.

인기

일반적으로 B- 트리를 가장 많이 실행했습니다. 비트 맵 인덱스는 카디널리티가 낮은 값 (부울 또는 성별을 생각할 수도 있음)에 대한 또 다른 옵션입니다. 사용 가능한 인덱스 유형에 따라 데이터베이스 엔진에 따라 달라집니다.

NoSQL

NoSQL 데이터베이스는 확실히 인덱스를 지원합니다. 대부분 B- 트리 또는 B- 트리의 변형을 지원합니다. 대부분 해시 인덱스도 지원하는 것 같습니다.


4
나는 B + 나무의 레벨 수가 고정되어 있다고 생각하지 않습니다. 내가 아는 한 적어도 SQL Server에는 없습니다.
ypercubeᵀᴹ

1
사실입니다. B- 트리는 여러 수준을 가질 수 있지만 일반적으로 3 또는 4로 제한됩니다. 내 답변을 편집했습니다.
sarme

안녕하세요 @sarme. 나는 당신의 대답을 정말로 좋아합니다. 많은 설명이 있습니다. 이 질문에 대해 현상금을 시작해도 괜찮습니까? 아마도 누군가 흥미로운 것을 추가 할 것입니다.
ruhungry

1
비트 맵 인덱스의 카디널리티가 낮다는 것을 의미하지 않습니까?
Mihai

1
맞습니다. 낮은 카디널리티. 취침 시간 직전에 질문에 대한 답변을 중단해야합니다 :). 답변이 업데이트되었습니다.
sarme

4

두 솔루션의 장점과 단점은 무엇입니까? 두 번째 솔루션은 범위 스캔을 수행 할 수 없습니다. 단일 ID를 선택하는 데 좋습니다. 그러나 ID 3에서 8을 원한다면 어떻게해야합니까? 실제 세계에서는 검색 할 O (1) * 6 레코드가 아닌 모든 레코드를 개별적으로 가져와야합니다. HashMap 인덱스가있는 대규모 프로덕션 데이터베이스에서는 다른 페이지에서 레코드를 가져 와서 디스크를 누르고 6 개의 다른 페이지를 메모리로 읽어야합니다.

B- 트리 구조에서 첫 번째 상황이 실제로 구현되는 방식과 같이 ID는 디스크에서 순차적이며 단일 페이지는 ID 3-8을 보유 할 수 있으며 범위 스캔 속도를 높이면 개별 액세스 O (log n)가됩니다. .

현재 데이터베이스 구현에서 어느 것이 더 인기가 있습니까? 다른 DB가 다른 접근법을 사용하고 있습니까? 많은 다른 데이터베이스에서 큰 경험이 없습니다. Sql Server는 주로 B-Tree를 사용하지만 SQl 2014에는 특정 테이블에서 사용할 수있는 새로운 해시 인덱스가 있습니다. 나는 No Sql 데이터베이스와 개별 레코드를 검색하여 작성된 캐싱 데이터베이스가 해시 인덱스를 사용한다고 들었습니다. 이는 사용자 A에 대한 레코드를 원하고 범위 스캔이 필요하지 않기 때문에 캐시에 적합합니다.

비 SQL DB에 존재합니까? 예. postgressql에 대한 인덱스 생성 문서를 간단히 살펴보면 Hash 및 B-Tree 인덱스뿐만 아니라 다른 몇 가지도 지원합니다.

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