힙(클러스터형 인덱스가 없는 테이블)Heaps (Tables without Clustered Indexes)

이 항목은 다음에 적용됩니다. 예SQL Server(2016부터)예Azure SQL Database아니요Azure SQL Data Warehouse아니요병렬 데이터 웨어하우스 THIS TOPIC APPLIES TO: yesSQL Server (starting with 2016)yesAzure SQL DatabasenoAzure SQL Data Warehouse noParallel Data Warehouse

힙이란 클러스터형 인덱스가 없는 테이블입니다.A heap is a table without a clustered index. 힙으로 저장된 테이블에서 하나 이상의 비클러스터형 인덱스를 만들 수 있습니다.One or more nonclustered indexes can be created on tables stored as a heap. 데이터는 순서를 지정하지 않고 힙에 저장됩니다.Data is stored in the heap without specifying an order. 일반적으로 데이터는 처음에 행이 테이블에 삽입되는 순서대로 저장되지만 데이터베이스 엔진Database Engine 에서 힙 안의 데이터를 이동하여 행을 효율적으로 저장할 수 있습니다. 따라서 데이터 순서는 예측할 수 없습니다.Usually data is initially stored in the order in which is the rows are inserted into the table, but the 데이터베이스 엔진Database Engine can move data around in the heap to store the rows efficiently; so the data order cannot be predicted. 힙에서 반환되는 행의 순서를 지정하려면 ORDER BY 절을 사용해야 합니다.To guarantee the order of rows returned from a heap, you must use the ORDER BY clause. 행의 저장소 순서를 지정하려면 테이블에서 클러스터형 인덱스를 만들어 테이블이 힙이 되지 않도록 합니다.To specify the order for storage of the rows, create a clustered index on the table, so that the table is not a heap.

참고

클러스터형 인덱스를 만들지 않고 테이블을 힙으로 두면 좋은 몇 가지 이유가 있지만, 힙을 효율적으로 사용하려면 고급 기술이 요구됩니다.There are sometimes good reasons to leave a table as a heap instead of creating a clustered index, but using heaps effectively is an advanced skill. 힙을 테이블로 두어야 할 이유가 없는 한 대부분의 테이블에는 신중하게 선택된 클러스터형 인덱스가 있어야 합니다.Most tables should have a carefully chosen clustered index unless a good reason exists for leaving the table as a heap.

힙을 사용하는 경우When to Use a Heap

테이블이 힙이고 비클러스터형 인덱스가 없는 경우 행을 찾으려면 전체 테이블을 검사(테이블 검색)해야 합니다.If a table is a heap and does not have any nonclustered indexes, then the entire table must be examined (a table scan) to find any row. 회사의 12개 지사 목록과 같이 테이블이 작은 경우에는 이렇게 하는 것이 문제가 되지 않을 수도 있습니다.This can be acceptable when the table is tiny, such as a list of the 12 regional offices of a company.

테이블을 힙으로 저장하면 파일 번호, 데이터 페이지 번호 및 페이지의 슬롯으로 구성된 RID(행 식별자)에 대한 참조로 개별 행이 식별됩니다.When a table is stored as a heap, individual rows are identified by reference to a row identifier (RID) consisting of the file number, data page number, and slot on the page. 행 ID는 작고 효율적인 구조입니다.The row id is a small and efficient structure. 데이터 설계자는 비클러스터형 인덱스를 통해 항상 데이터에 액세스하고 RID가 클러스터형 인덱스 키보다 작은 경우에 힙을 사용합니다.Sometimes data architects use heaps when data is always accessed through nonclustered indexes and the RID is smaller than a clustered index key.

힙을 사용하지 않는 경우When Not to Use a Heap

데이터가 주로 정렬된 순서대로 반환되는 경우에는 힙을 사용하지 않습니다.Do not use a heap when the data is frequently returned in a sorted order. 정렬 열에 대해 클러스터형 인덱스를 사용하면 정렬 작업이 필요하지 않습니다.A clustered index on the sorting column could avoid the sorting operation.

데이터를 자주 그룹화하는 경우 힙을 사용하지 않습니다.Do not use a heap when the data is frequently grouped together. 데이터를 그룹화하기 전에 데이터를 정렬해야 하며, 정렬 열에 대해 클러스터형 인덱스를 사용하면 정렬 작업이 필요하지 않습니다.Data must be sorted before it is grouped, and a clustered index on the sorting column could avoid the sorting operation.

테이블에서 데이터 범위를 자주 쿼리하는 경우 힙을 사용하지 않습니다.Do not use a heap when ranges of data are frequently queried from the table. 범위 열에 대해 클러스터형 인덱스를 사용하면 전체 힙을 정렬할 필요가 없습니다.A clustered index on the range column will avoid sorting the entire heap.

비클러스터형 인덱스가 없고 테이블이 큰 경우 힙을 사용하지 않습니다.Do not use a heap when there are no nonclustered indexes and the table is large. 힙에서 행을 찾으려면 힙의 모든 행을 읽어야 합니다.In a heap, all rows of the heap must be read to find any row.

힙 관리Managing Heaps

힙을 만들려면 클러스터형 인덱스가 없는 테이블을 만듭니다.To create a heap, create a table without a clustered index. 테이블에 이미 클러스터형 인덱스가 포함되어 있는 경우 클러스터형 인덱스를 삭제하여 테이블을 힙에 반환합니다.If a table already has a clustered index, drop the clustered index to return the table to a heap.

힙을 제거하려면 힙에 클러스터형 인덱스를 만듭니다.To remove a heap, create a clustered index on the heap.

힙을 다시 작성하여 불필요하게 사용된 공간을 복구하려면 힙에 클러스터형 인덱스를 만든 다음 해당 클러스터형 인덱스를 삭제합니다.To rebuild a heap to reclaim wasted space, create a clustered index on the heap, and then drop that clustered index.

경고

클러스터형 인덱스를 만들거나 삭제하면 전체 테이블을 다시 쓸 필요가 없습니다.Creating or dropping clustered indexes requires rewriting the entire table. 테이블에 비클러스터형 인덱스가 포함되어 있는 경우 클러스터형 인덱스가 변경될 때마다 모든 비클러스터형 인덱스를 다시 만들어야 합니다.If the table has nonclustered indexes, all the nonclustered indexes must all be recreated whenever the clustered index is changed. 따라서 힙을 클러스터형 인덱스 구조로 변경하거나 클러스터형 인덱스를 힙으로 변경하면 tempdb에서 데이터를 다시 정렬하는 데 많은 디스크 공간이 필요하고 많은 시간이 소요될 수 있습니다.Therefore, changing from a heap to a clustered index structure or back can take a lot of time and require disk space for reordering data in tempdb.

힙 구조Heap Structures

힙이란 클러스터형 인덱스가 없는 테이블입니다.A heap is a table without a clustered index. 힙에는 힙에서 사용하는 각 파티션에 대해 sys.partitions index_id = 0 행이 하나 있습니다.Heaps have one row in sys.partitions, with index_id = 0 for each partition used by the heap. 기본적으로 힙은 단일 파티션을 사용합니다.By default, a heap has a single partition. 힙이 다중 파티션을 사용하는 경우 각 파티션은 해당 특정 파티션에 대한 데이터를 포함하는 힙 구조를 갖습니다.When a heap has multiple partitions, each partition has a heap structure that contains the data for that specific partition. 예를 들어 힙이 4개의 파티션을 사용하면 파티션마다 하나씩 총 4개의 힙 구조가 있습니다.For example, if a heap has four partitions, there are four heap structures; one in each partition.

힙의 데이터 형식에 따라 각 힙 구조에는 특정 파티션에 대한 데이터를 저장하고 관리하는 할당 단위가 하나 이상 있습니다.Depending on the data types in the heap, each heap structure will have one or more allocation units to store and manage the data for a specific partition. 최소한 각 힙에는 파티션당 하나의 IN_ROW_DATA 할당 단위가 있습니다.At a minimum, each heap will have one IN_ROW_DATA allocation unit per partition. 또한 힙에는 LOB(Large Object) 열이 포함된 경우 파티션당 하나의 LOB_DATA 할당 단위가 있으며The heap will also have one LOB_DATA allocation unit per partition, if it contains large object (LOB) columns. 8,060바이트 행 크기 제한을 초과하는 가변 길이 열이 포함된 경우 파티션당 하나의 ROW_OVERFLOW_DATA 할당 단위도 있습니다.It will also have one ROW_OVERFLOW_DATA allocation unit per partition, if it contains variable length columns that exceed the 8,060 byte row size limit.

first_iam_page 시스템 뷰의 sys.system_internals_allocation_units 열은 특정 파티션의 힙에 할당된 공간을 관리하는 IAM 페이지 체인에서 첫 번째 IAM 페이지를 가리킵니다.The column first_iam_page in the sys.system_internals_allocation_units system view points to the first IAM page in the chain of IAM pages that manage the space allocated to the heap in a specific partition. SQL Server에서는 IAM 페이지를 사용하여 힙 간을 이동합니다.SQL Server uses the IAM pages to move through the heap. IAM 데이터 페이지와 내부의 행은 특정 순서로 정렬되어 있지 않으며 연결되어 있지도 않습니다.The data pages and the rows within them are not in any specific order and are not linked. 데이터 페이지 간의 유일한 논리적 연결은 IAM 페이지에 기록된 정보입니다.The only logical connection between data pages is the information recorded in the IAM pages.

중요

sys.system_internals_allocation_units 시스템 뷰는 Microsoft SQL Server 내부 전용으로 예약되었습니다.The sys.system_internals_allocation_units system view is reserved for Microsoft SQL Server internal use only. 향후 호환성은 보장되지 않습니다.Future compatibility is not guaranteed.

IAM을 검색하여 힙의 페이지를 보유하는 익스텐트를 찾음으로써 힙의 테이블 검색 또는 연속 읽기를 수행할 수 있습니다.Table scans or serial reads of a heap can be performed by scanning the IAM pages to find the extents that are holding pages for the heap. IAM은 익스텐트가 파일에 존재하는 순서와 동일하게 익스텐트를 나타내므로 각 파일에서 차례로 연속 힙 검색이 진행됩니다.Because the IAM represents extents in the same order that they exist in the data files, this means that serial heap scans progress sequentially through each file. 또한 IAM 페이지를 사용하여 검색 시퀀스를 설정하면 힙의 행이 삽입되는 순서대로 반환되지 않습니다.Using the IAM pages to set the scan sequence also means that rows from the heap are not typically returned in the order in which they were inserted.

다음 그림에서는 SQL Server 데이터베이스 엔진에서 IAM 페이지를 사용하여 단일 파티션 힙에서 데이터 행을 검색하는 방법을 보여 줍니다.The following illustration shows how the SQL Server Database Engine uses IAM pages to retrieve data rows in a single partition heap.

iam_heap

CREATE INDEX(Transact-SQL)CREATE INDEX (Transact-SQL)

DROP INDEX(Transact-SQL)DROP INDEX (Transact-SQL)

클러스터형 및 비클러스터형 인덱스 소개Clustered and Nonclustered Indexes Described