
use-the-index-luke 저자 Markus Winand
---------------------------------------------
Markus Winand는 SQL에 대한 통찰력을 제공하고 다양한 시스템이 SQL을 지원하는 방법을 modern-sql.com 에서 보여줍니다. 이전에 그는 use-the-index-luke.com 을 만들었는데, 지금도 활발하게 유지되고 있습니다. Markus는 winand.at 를 통해 강사, 연사 및 컨설턴트로 고용될 수 있습니다.
---------------------------------------------
You can upload a Korean translation of use-the-index-luke.com on your blog
Thank you from the bottom of my heart to author Makus Winand for allowing me.
These are translations that I use for studying by using a papago (google translate)
The translations may not be correct or there may be a typo.
I'd appreciate it if you could point it out in the comments.
---------------------------------------------
---------------------------------------------
use-the-index-luke.com 의 한글번역본을 블로그에 업로드 해도 된다고
허락해주신 Makus Winand 저자님께 진심으로 감사합니다.
이 번역본들은 제가 공부용도로 번역기(papago, google transrate)를 돌려서
번역한 내용들이라 맞지 않거나, 오타가 있을수 있습니다.
댓글로 지적해주시면 감사하겠습니다.
---------------------------------------------
https://use-the-index-luke.com/sql/clustering/index-organized-clustered-index
ㄴ인덱스 구성 테이블 및 클러스터된 인덱스
인덱스 전용 검색은 인덱스에 저장된 중복 데이터만 사용하여 SQL문을 실행합니다.
힙 테이블의 원래 데이터는 필요하지 않습니다. 만약 우리가 그 개념을 다음 단계로 끌어올리고 모든 열을 인덱스에 넣으면, 당신은 왜 우리가 힙 테이블이 필요한지 궁금해 할 것입니다.
일부 데이터베이스는 Index을 주 테이블 저장소로 사용할 수 있습니다. Oracle 데이터베이스에서는 이 개념을 IOT(index-organized tables)이라고 부르고, 다름 데이터베이스에서는 클러스터형 인덱스하는 용어를 사용합니다. 이 섹션 에서는 두 용어를 사용하며 필요에 따라 표 또는 인덱스 특성을 강조합니다.
따라서 인덱스로 구성된 테이블은 힙 테이블이 없는 B-Tree Index 입니다. 따라서 (1)힙 구조를 위한 공간을 절약하고, (2)클러스터된 인덱스의 모든 액세스는 자동으로 인덱스 전용 검색이 됩니다. 두 가지 이점 모두 유망한 것처럼 들리지만 실제로 달성하기는 어렵습니다.
인덱스로 구성된 테이블의 단점은 동일한 테이블에 다른 인덱스와 유사하게 2차 인덱스는 클러스터된 인덱스에 저장된 원래 테이블 데이터를 나타냅니다. 여기서 데이터는 힙 테이블에서와 같이 정적으로 저장되지않지만 인덱스 순서를 유지하기 위해 언제든지 이동할 수 있습니다. 따라서 인덱스 구성 테이블에 있는 행의 실제 위치를 보조 인덱스에 저장할 수 없습니다. 대신 데이터베이스에서 논리 키를 사용해야합니다.
다음 그림은 2012년 5월 23일에 모든 매출을 찾기 위한 지수 조회를 보여줍니다.
비교를 위해 먼저 힙 테이블을 사용할 때의 프로세스를 보여주는 그림 5.2를 살펴보겠습니다.
실행에는 (1) INDEX RANGE SCAN(INDEX RANGE SCAN), (2) TABLE ACCESS by INDEX ROWID의 두 단계가 포함됩니다.
Figure 5.2 Index-Based Access on a Heap Table

----------------------------------------------------------
테이블 액세스가 병목 현상이 될 수 있지만 인덱스에 테이블 행에 대한 직접 포인터로 ROWID가 있기 때문에 테이블 액세스는 행당 하나의 읽기 작업으로 제한됩니다. 인덱스의 위치가 정확하기 때문에 데이터베이스는 힙 테이블에서 행을 즉시 로드할 수 있습니다.
그러나 인덱스로 구성된 테이블에서 보조 인덱스를 사용하면 사진이 변경됩니다. 보조 인덱스는 물리적 포인터(ROWID)를 저장하지 않고 클러스터된 인덱스의 키 값(이른바 클러스터링키)만 저장합니다.
종종 이 키는 인덱스로 구성된 테이블의 기본 키입니다.
----------------------------------------------------------
Why Secondary Indexes have no ROWID
보조 인덱스에 ROWID가 없는 이유
테이블 행에 대한 직접 포인터는 보조 인덱스에도 적합합니다. 그러나 테이블 행이 고정된 저장 위치에 있을경우에만 가능합니다. 안타깝게도 행이 순서대로 유지되는 인덱스 구조의 일부인 경우에는 불가능합니다. 인덱스 순서를 유지하려면 행을 가끔 이동해야합니다. 이는 행 자체에 영향을 미치지 않는 작업에도 해당됩니다. 예를 들어, 삽입 문은 리프 노드를 분할하여 새 항목을 위한 공간을 확보할 수 있습니다. 즉, 일부 항목이 다른 위치에 있는 새 데이터 블록으로 이동됩니다.
그러나 힙 테이블은 행을 순서대로 유지하지 않습니다. 데이터베이스는 충분한 공간을 찾을 때마다 새 항목을 저장합니다. 데이터는 한 번 작성되면 힙 테이블에서 이동하지 않습니다.
----------------------------------------------------------
보조 인덱스에 액세스하면 ROWID가 아니라 클러스터된 인덱스를 검색하기 위한 논리 키가 제공됩니다. 그러나 단일 액세스로는 클러스터된 인덱스를 검색하기에 충분하지 않습니다. 전체 Tree 순회가 필요합니다. 즉, 보조 인덱스를 통해 테이블에 액세스하면 보조 인덱스를 한 번(INDEX RANGE SCAN) 검색한 다음 보조 인덱스에 있는 각 행에 대한 클러스터된 인덱스(INDEX UNIQUE SCAN)을 검색합니다.
Figure 5.3 Secondary Index on an IOT
----------------------------------------------------------

----------------------------------------------------------
그림 5.3은 클러스터된 인덱스의 B-Tree가 2차 인덱스와 테이블 데이터 사이에 있음을 보여줍니다.
보조 인덱스를 통해 인덱스로 구성된 테이블에 액세스하는 것은 매우 비효율적이며, 힙 테이블에서 테이블 액세스를 방지하는 것과 같은 방식으로 방지할 수 있습니다.
이 경우 "보조 인덱스만 검색"이라고 더 잘 설명됩니다. 인덱스 전용 검색의 성능 이점은 단일 액세스뿐만 아니라 전체 인덱스 고유 검색을 방지하기 때문에 더욱 큽니다.
----------------------------------------------------------
Important
보조 인덱스를 통해 인덱스 구성 테이블에 액세스하는 것은 매우 비효율적입니다.
----------------------------------------------------------
또한 이 예제를 사용하여 데이터베이스가 보유한 모든 중복성을 이용하는 것을 확인할 수 있습니다. 보조 인덱스는 각 인덱스 항목에 대한 클러스터링 키를 저장합니다.
따라서 인덱스 구성 테이블에 액세스하지 않고도 보조 인덱스에서 클러스터링 키를 쿼리할 수 있습니다.
----------------------------------------------------------
SELECT sale_id
FROM sales_iot
WHERE sale_date = ?
----------------------------------------------------------
----------------------------------------------------------
-------------------------------------------------
| Id | Operation | Name | Cost |
-------------------------------------------------
| 0 | SELECT STATEMENT | | 4 |
|* 1 | INDEX RANGE SCAN| SALES_IOT_DATE | 4 |
-------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("SALE_DATE"=:DT)
----------------------------------------------------------
SALES_IOT 테이블은 SALE_ID를 클러스터링 키로 사용하는 인덱스 구성 테이블입니다. SALE_IOT_DATE 인덱스는 SALE_DATE 열에만 있지만 클러스터링 키 SALE_ID의 복사본이 있으므로 보조 인덱스만 사용하여 쿼리를 충족할 수 있습니다.
다른 열을 선택할 때 데이터베이스는 각 행에 대해 클러스터된 인덱스에서 INDEX UNIQUE SCAN을 실행해야 합니다:
----------------------------------------------------------
SELECT eur_value
FROM sales_iot
WHERE sale_date = ?
----------------------------------------------------------
----------------------------------------------------------
---------------------------------------------------
| Id | Operation | Name | Cost |
---------------------------------------------------
| 0 | SELECT STATEMENT | | 13 |
|* 1 | INDEX UNIQUE SCAN| SALES_IOT_PK | 13 |
|* 2 | INDEX RANGE SCAN| SALES_IOT_DATE | 4 |
---------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("SALE_DATE"=:DT)
2 - access("SALE_DATE"=:DT)
----------------------------------------------------------
인덱스로 구성된 테이블과 클러스터된 인덱스는 결국 언뜻 보기만큼 유용하지 않습니다. 보조 인덱스를 사용하면 클러스터된 인덱스의 성능 향상이 쉽게 손실됩니다.
클러스터링 키는 일반적으로 ROWID보다 길기 때문에 보조인덱스가 힙 테이블에 있는 것보다 크기 때문에 종종 힙 테이블을 생략할 때 절약되는 비용을 제거합니다. 인덱스로 구성된 테이블과 클러스터된 인덱스의 강도는 대부분 두 번째 인덱스가 필요하지 않은 테이블로 제한됩니다. 힙 테이블은 쉽게 참조할 수 있는 고정 마스터 복사본을 제공하는 이점이 있습니다.
----------------------------------------------------------
Important
인덱스가 하나만 있는 테이블은 클러스터된 인덱스 또는 인덱스 구성 테이블로 구현하는 것이 가장 좋습니다.
인덱스가 더 많은 테이블은 종종 힙 테이블의 이점을 얻을 수 있습니다. 인덱스 전용 검색을 사용하여 테이블 액세스를 방지할 수 있습니다. 이렇게 하면 다른 인덱스의 속도를 늦추지 않고 클러스터된 인덱스의 성능을 선택할 수 있습니다.
----------------------------------------------------------
인덱스로 구성된 테이블과 클러스터된 인덱스에 대한 데이터베이스 지원은 매우 일관되지 않습니다. 다음 개요에서는 가장 중요한 세부 사항을 설명합니다.
----------------------------------------------------------
Oracle
Oracle 데이터베이스는 기본적으로 힙 테이블을 사용합니다. ORGANIZTION INDEX 절을 사용하여 인덱스로 구성된 테이블을 만들 수 있습니다 :
CREATE TABLE (
id NUMBER NOT NULL PRIMARY KEY,
[...]
) ORGANIZATION INDEX
Oracle 데이터베이스는 항상 기본 키를 클러스터링 키로 사용합니다.
----------------------------------------------------------