2016-06-29 3 views
0

집계 함수를 사용하여 SQL 쿼리를 사용할 때 성능 문제가 발생하므로 인덱스 생성이 정확하게 작동하는 방식을 이해하는 것이 좋습니다. 내가 이해할 수없는 한 가지 건너 온 :Oracle 색인 생성 구문

SELECT SUM(field1) FROM table1 WHERE timeofrequest BETWEEN 1 AND 2; 

:

1.)CREATE INDEX FIELD1_INDEX ON TABLE1 (FIELD1) ONLINE TABLESPACE XXX; 
    CREATE INDEX timeofrequest_INDEX ON TABLE1 (timeofrequest) ONLINE TABLESPACE XXX; 

2.)CREATE INDEX COMBINED_INDEX ON TABLE1 (FIELD1, FIELD2) ONLINE TABLESPACE XXX; 

내가 부탁 해요 이유는이 두 작성 지침?의 차이가 무엇인지 내가 같은 쿼리를 가지고있다 Table1에는 많은 양의 데이터가 들어 있으므로이 쿼리는 준비하는 데 20 초 이상이 걸립니다. 긴 런타임을 피하기 위해 접근 방식 1을 사용하고 영향을받는 각 필드에 대한 인덱스를 만들려고했습니다. 사실 너무 느립니다. 실행 계획을 분석 한 결과 timeofrequest 인덱스가 사용되었지만 field1 인덱스는 사용되지 않았습니다. 한 문장으로 결합 된 문장을 만들면 도움이 될까요? 어떤 차이가 있습니까?

답변

0

첫 번째 두 개의 인덱스가 세 번째 인덱스와 다르므로 첫 두 개의 인덱스는 인덱스에 대해 SINGLE 열만 사용합니다. 세 번째 색인은 색인에 대해 두 개의 다른 열로 구성되지만 세 번째 색인은 색인에 나열된 첫 번째 열만 제공하더라도 ... 복합 색인이라고도합니다. 오라클은 실제로 단일 쿼리 문 내에서 SINGLE 인덱스 만 활용할 수 있으며 CBO는 사용할 최상의 옵션을 찾아냅니다.

첫 번째 예에서는 개별 열에 대해 두 개의 인덱스가 있습니다. 두 번째 예는 두 개의 열이있는 단일 색인입니다. 귀하의 첫 번째 예제는 오직 하나 또는 다른 하나만 사용하지만 주어진 단일 선택 진술 (CBO는 귀하의 쿼리를 기반으로 무엇을 사용할지 결정합니다)에 대해 둘 다 사용하지는 않습니다.

예 :

SELECT SUM(field1) FROM table1 WHERE timeofrequest BETWEEN 1 AND 2; 

이것은 단지 당신이 timeofrequest에 배치 한 인덱스를 사용하려고 시도합니다. 실제로 범위 스캔을 시도합니다. 두 번째 인덱스

예 : 이것은 당신이 자리에있는 COMBINED_INDEX을 활용하고 인덱스의 첫 번째 필드에 따라 모든 레코드를 가져 오는 것입니다 만 'FIELD1'에 대한 인덱스를 가지고 있지 않은 가정

SELECT SUM(field1) FROM table1 WHERE FIELD1 = 'x'; 

.

당신이 가지고있는 경우 : 인덱스가 먼저, FIELD2을 FIELD1를 사용하여 주위를 내장으로

SELECT SUM(field1) FROM table1 WHERE FIELD2 = 'y'; 

이의 combined_index를 사용하지 것이다.

당신이 있다면 :

SELECT SUM(field1) FROM table1 WHERE FIELD1 = 'x' and FIELD2 = 'y'; 

이 여전히 COMBINED_INDEX을 활용하는 것이지만, 여기 당신이 단위의 미세한 수준을 제공합니다. 전체 색인 (field1 및 field2 ...)을 사용하여 행을 훨씬 빠르게 반환합니다. 왜 이것이 유용한가요? 음, FIELD1에 대한 색인을 가질 수 있으며, 단지 field1에서만 검색하면 수천 (또는 수만 또는 수백만)의 레코드가 생성되므로 다른 열을 색인의 일부로 제공 할 수 있습니다 필요한 레코드를 대상으로하는 데 도움이됩니다 ... 차례로 더 높은 선택성을 제공합니다.

중요 사항! CBO는 최선의 접근 방법을 찾아 냈습니다. 카디널리티가 낮 으면 (연구 테이블 카디널리티 ...)를 사용하면 해당 인덱스를 전혀 사용하지 않을 수도 있으며 CBO에 따라 전체 테이블 스캔이 더 나을 수도 있습니다. 카디널리티가 높지만 여전히 인덱스를 사용하고 있지 않다면 테이블과 인덱스를 분석 한 다음 Explain 계획을 다시 실행하여 새로운 결과가 나오는지 확인해야 할 수 있습니다. 테이블의 데이터가 너무 많이 변경되어 최근에 분석 된 데이터가 없기 때문에 카디널리티가 낮을 수도 있습니다. 표/색인을 분석하는 것은 매우 중요한 일이며 쉽게 간과 될 수 있습니다. 여러 차례에 걸쳐 나는 테이블이나 인덱스를 다시 분석하는 것만으로도 놀라운 개선이 이루어 졌다는 것을 발견했습니다.

분석 테이블 및 DBMS_STATS의 사용을 검토하십시오. 당신은 방대한 양의 데이터를 가지고 있고, 당신의 "시간 요청"열이 정말에만 어쩌면 천만 기록 테이블의 값 (의 작은 구별이 있는지

https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_stats.htm

또 다른 해결책은 너무에만있을 것이 20 개의 고유 한 값 ..)을 사용하면 분할 된 테이블을 설정하고 거기에서 인덱스를 제공 할 수 있습니다. 그것은 쿼리 성능 시간을 크게 향상시킵니다.

+0

고맙습니다. 도움을 주셔서 감사합니다. –