2017-11-15 1 views
0

employee 테이블의 created_date 열에 인덱스를 만들었지 만 아래 쿼리의 explain 플랜을 볼 때 인덱스가 사용되지 않습니다. 왜 ?order by 절에서 색인을 사용 하시겠습니까?

Select * from employee order by created_date desc; 

광의 이해에 따라 oracle은 행 ID와 함께 (B 트리를 사용하여) 생성 된 날짜를 정렬 된 방식으로 유지합니다. 그래서 왜 이미 정렬 된 데이터를 사용하지 않고 행 ID를 사용하여 다른 데이터를 가져 옵니까?

인덱스를 사용하지 않으면 메모리의 모든 데이터를 가져 와서 정렬하고 반환합니다. 그렇지 않니?

+3

테이블의 모든 행을 선택하기 때문입니다. 오라클이 모든 것을 포착해야하므로 색인을 사용할 필요가 없습니다. – Ben

답변

0

기본 테이블에서 모든 행을 읽어야합니다. 맞습니까? 디스크에서 모든 것을 읽으려면 가장 빠른 방법은 디스크의 순서에 관계없이 블록 단위로 블록 단위로 읽는 것입니다. 이렇게하면 하드 디스크에서 읽는 횟수가 최소화됩니다.

무엇을 제안하고 있습니까 :

색인을보십시오. 가장 최근 날짜가있는 행의 ROWID를 찾아 디스크에서 한 행을 읽으십시오. 그런 다음 다음 행의 ROWID를 찾아 디스크에서 해당 행을 읽으십시오. 반복. 하나는 테이블의 각 행에 대해 디스크에서 읽습니다.

예, 그렇게하면 행이 이미 정렬되어 있습니다 (행을 정렬하기 위해 CPU 작업을하지 않아도 됨). 그러나 디스크에서 더 많은 읽기 작업이 있습니다. 숫자를 구성하기 위해 0.8 초의 CPU 작업을 줄이고 I/O 시간을 40 초 늘립니다. (순수하게 구성되었지만 비교에서 정확한 순서가 가능할 것입니다.)

+0

감사합니다. 알았다. 한 가지 질문은 oracle이 모든 행을 블록 단위로 읽고, 메모리에서 정렬 한 다음 결과를 반환한다는 것입니다. – user3198603

1

created_date 열이 null 일 가능성이 가장 높습니다. where created_date is not null 위해 CREATED_DATE 내림차순으로 직원에서 쿼리

where created_date is not null 

,

선택 * 추가;

그리고 explain plan을 다시보십시오.

인덱스를 사용할 수는 없지만 전체 스캔이 필요하지 않은 경우가 가장 많이 사용됩니다.

오라클 데이터 크기에 대한 검사 (우리는 수동으로도, dba_tables에서 조회 할 수있다), 경우 CBO (Cost based optimization, 시스템의 대부분이을 (쿼리가 10 % 이상을 반환하는 경우, 일반적으로 인덱스를 필요로하지 않는다) 최적화 유형이 Rule-based optimization 대신 사용됨) 및 관련 테이블이 분석됩니다.

  • CBO 비용이 작업을 완료하는 데 필요한 시스템 자원에 관한 가장 낮은 비용과 하나 따기, 여러 execution plans를 생성하기 위해 데이터베이스 통계를 사용합니다.
+0

감사합니다. Barbaros. 오라클이 얼마나 많은 데이터가 반환되는지 (예 : 10 %) 오라클이 인덱스를 retuened해야하는지 여부를 결정한다는 것을 의미합니까? – user3198603

+0

@ user3198603 그렇습니다. 오라클은 CBO (비용 기반 최적화, 대부분의 시스템에서 규칙 기반 opt 대신 선호되는 이러한 유형의 최적화)가 사용되는 경우 데이터 크기 (dba_tables에서 직접 쿼리 할 수도 있음)를 확인합니다. 관련 테이블을 분석했습니다. –

+0

한 가지 질문으로 oracle이 메모리의 모든 행을 읽고 메모리에서 정렬 한 다음 결과를 반환합니다. – user3198603