SQL Server 인덱스-오름차순 또는 내림차순으로 어떤 차이가 있습니까?
MS SQL Server에서 열 또는 열 수에 대한 색인을 작성할 때 (버전 2005를 사용하고 있음) 각 열의 색인이 오름차순 또는 내림차순으로 지정되도록 지정할 수 있습니다. 이 선택이 왜 여기에 있는지 이해하는 데 어려움을 겪고 있습니다. 이진 정렬 기술을 사용하면 조회 속도가 빠르지 않습니까? 어떤 순서를 선택하면 어떤 차이가 있습니까?
이것은 복합 인덱스와 함께 사용될 때 주로 중요합니다.
CREATE INDEX ix_index ON mytable (col1, col2 DESC);
다음 중 하나에 사용할 수 있습니다.
SELECT *
FROM mytable
ORDER BY
col1, col2 DESC
또는:
SELECT *
FROM mytable
ORDER BY
col1 DESC, col2
그러나
SELECT *
FROM mytable
ORDER BY
col1, col2
단일 열의 인덱스는 두 가지 방법으로 정렬하는 데 효율적으로 사용될 수 있습니다.
자세한 내용은 내 블로그의 기사를 참조하십시오.
최신 정보:
실제로 이것은 단일 열 인덱스의 경우에도 중요 할 수 있지만 그렇게 명확하지는 않습니다.
클러스터 된 테이블의 열에 대한 인덱스를 상상해보십시오.
CREATE TABLE mytable (
pk INT NOT NULL PRIMARY KEY,
col1 INT NOT NULL
)
CREATE INDEX ix_mytable_col1 ON mytable (col1)
인덱스는 col1
정렬 된 값 col1
과 행 참조를 유지합니다.
테이블이 클러스터되어 있으므로 행에 대한 참조는 실제로의 값입니다 pk
. 또한의 각 값 내에서 주문됩니다 col1
.
이것은 인덱스의 잎이 실제로 on에 정렬되어 있음을 의미하며이 (col1, pk)
쿼리는 다음과 같습니다.
SELECT col1, pk
FROM mytable
ORDER BY
col1, pk
정렬이 필요 없습니다.
다음과 같이 인덱스를 생성하면
CREATE INDEX ix_mytable_col1_desc ON mytable (col1 DESC)
그런 다음의 값은 col1
내림차순으로 정렬되지만 pk
각 값 내의 값은 col1
오름차순으로 정렬됩니다.
이것은 다음 쿼리를 의미합니다.
SELECT col1, pk
FROM mytable
ORDER BY
col1, pk DESC
에 의해 제공 될 수 ix_mytable_col1_desc
있지만에 의해 제공 될 수는 없습니다 ix_mytable_col1
.
다시 말해, CLUSTERED INDEX
임의의 테이블에서 를 구성하는 열 은 항상 해당 테이블에서 다른 인덱스의 후행 열입니다.
For a true single column index it makes little difference from the Query Optimiser's point of view.
For the table definition
CREATE TABLE T1( [ID] [int] IDENTITY NOT NULL,
[Filler] [char](8000) NULL,
PRIMARY KEY CLUSTERED ([ID] ASC))
The Query
SELECT TOP 10 *
FROM T1
ORDER BY ID DESC
Uses an ordered scan with scan direction BACKWARD
as can be seen in the Execution Plan. There is a slight difference however in that currently only FORWARD
scans can be parallelised.
However it can make a big difference in terms of logical fragmentation. If the index is created with keys descending but new rows are appended with ascending key values then you can end up with every page out of logical order. This can severely impact the size of the IO reads when scanning the table and it is not in cache.
See the fragmentation results
avg_fragmentation avg_fragment
name page_count _in_percent fragment_count _size_in_pages
------ ------------ ------------------- ---------------- ---------------
T1 1000 0.4 5 200
T2 1000 99.9 1000 1
for the script below
/*Uses T1 definition from above*/
SET NOCOUNT ON;
CREATE TABLE T2( [ID] [int] IDENTITY NOT NULL,
[Filler] [char](8000) NULL,
PRIMARY KEY CLUSTERED ([ID] DESC))
BEGIN TRAN
GO
INSERT INTO T1 DEFAULT VALUES
GO 1000
INSERT INTO T2 DEFAULT VALUES
GO 1000
COMMIT
SELECT object_name(object_id) AS name,
page_count,
avg_fragmentation_in_percent,
fragment_count,
avg_fragment_size_in_pages
FROM
sys.dm_db_index_physical_stats(db_id(), object_id('T1'), 1, NULL, 'DETAILED')
WHERE index_level = 0
UNION ALL
SELECT object_name(object_id) AS name,
page_count,
avg_fragmentation_in_percent,
fragment_count,
avg_fragment_size_in_pages
FROM
sys.dm_db_index_physical_stats(db_id(), object_id('T2'), 1, NULL, 'DETAILED')
WHERE index_level = 0
It's possible to use the spatial results tab to verify the supposition that this is because the later pages have ascending key values in both cases.
SELECT page_id,
[ID],
geometry::Point(page_id, [ID], 0).STBuffer(4)
FROM T1
CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )
UNION ALL
SELECT page_id,
[ID],
geometry::Point(page_id, [ID], 0).STBuffer(4)
FROM T2
CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )
The sort order matters when you want to retrieve lots of sorted data, not individual records.
Note that (as you are suggesting with your question) the sort order is typically far less significant than what columns you are indexing (the system can read the index in reverse if the order is opposite what it wants). I rarely give index sort order any thought, whereas I agonize over the columns covered by the index.
@Quassnoi provides a great example of when it does matter.
'Programing' 카테고리의 다른 글
chrome-devtools가 실제로 모든 JS 소스를 검색하도록 할 수 있습니까? (0) | 2020.07.05 |
---|---|
'npm start'는 언제 사용하고 'ng serve'는 언제 사용합니까? (0) | 2020.07.05 |
Junit @ Before / @ After는 어떤 주문입니까? (0) | 2020.07.05 |
`m_` 변수 접두사는 무엇을 의미합니까? (0) | 2020.07.05 |
"권한이있는 SSL / TLS 보안 채널에 대한 신뢰 관계를 설정할 수 없음"해결 방법 (0) | 2020.07.04 |