문제

인덱스를 생성하지 않고 Oracle 쿼리의 쿼리 성능을 향상시키기 위해 무엇을 할 수 있습니까?

더 빠르게 실행하려는 쿼리는 다음과 같습니다.

SELECT c.ClaimNumber, a.ItemDate, c.DTN, b.FilePath
FROM items a,
itempages b,
keygroupdata c
WHERE a.ItemType IN (112,115,189,241)
AND a.ItemNum = b.ItemNum
AND b.ItemNum = c.ItemNum
ORDER BY a.DateStored DESC

이러한 열은 인덱싱되지 않으며 각 테이블에는 수백만 개의 레코드가 포함되어 있습니다.말할 필요도 없이 쿼리가 실행되는 데 3분 30초 이상이 걸립니다.이는 프로덕션 환경의 타사 데이터베이스이며 인덱스를 생성하는 것이 허용되지 않으므로 쿼리 자체에 성능 개선이 이루어져야 합니다.

감사해요!

도움이 되었습니까?

해결책

먼저 ANSI 표준으로 쿼리를 다시 작성했습니다.

SELECT c.ClaimNumber, a.ItemDate, c.DTN, b.FilePath
FROM items a
INNER JOIN itempages b ON b.ItemNum = a.ItemNum
INNER JOIN keygroupdata c ON c.ItemNum = b.ItemNum
WHERE a.ItemType IN (112,115,189,241)
ORDER BY a.DateStored DESC

이를 통해 무슨 일이 일어나고 있는지 더 쉽게 읽고 이해할 수 있습니다. 또한 실제 큰 문제를 일으킬 수있는 실수 (즉, 교차 결합)를 만들지 않도록 도와줍니다. 그런 다음 DBMS가 해당 쿼리로 무엇을하고 있는지 설명 할 설명 계획을 얻었습니다. 일부 인덱스를 사용하려고합니까? 테이블에 올바르게 결합하고 있습니까?

그런 다음 작업하고있는 테이블을 검토하여 쿼리를 더 빨리 만들기 위해 이미 사용할 수있는 색인이 있는지 확인했습니다. 마지막으로 다른 사람들이 제안한 것처럼 절에서 주문을 제거하고 코드로 수행 할 것입니다.

다른 팁

제 3 자에게 처음부터해야했던 것처럼 조인 열을 색인하도록 요청하십시오! 인덱스가 없으면 오라클은 무차별적인 힘 외에는 계속 될 것이 없습니다.

해당 테이블 중 하나에 구체화된 뷰를 생성해 볼 수 있습니다.그런 다음 쿼리 속도를 높이는 데 도움이 되는 구체화된 뷰에 인덱스를 생성할 수 있습니다(이 경우 원시 테이블 대신 구체화된 뷰를 쿼리하게 됩니다).

물론 기본 테이블이 업데이트되면 뷰와 인덱스를 새로 고쳐야 합니다.

먼저, 실행 계획을보십시오. 쿼리 실행의 각 단계에서 검색 할 행의 수를 정확하게 반영합니까? 술어는 "(112,115,189,241)의 a.itemtype"는 얼마나 선택적입니까? 실행 계획은 조인 또는 정렬에 임시 디스크 공간을 사용하는 것을 보여 주나요?

실제로 실행 계획을 포함하도록 질문을 수정할 수 있습니다.

또한 해시 조인 비활성화가 없는지 확인하십시오. 이는 Oracle에서 대량 데이터를 동등하는 가장 효율적인 방법이기 때문에 OLTP 터닝 시스템의 경우에도 마찬가지입니다. 그들은 처형 계획에 나타나야합니다.

여기에 표시된 것처럼 테이블에 가입하기 전에 항목 유형에서 필터링을 시도 할 수 있습니다.

9i 이전에 Oracle에서 실행중인 경우 때때로 놀라운 이점을 얻을 수 있습니다.

select 
  c.claimnumber,
  a.itemdate, 
  c.dtn,
  b.filepath
from 
  (
  select itemdate
  from items it
  where it.itemtype in(112,115,189,241)
  ) a
  itempages b,
  keygroupdata c
where a.itemnum = b.itemnum
  and b.itemnum = c.itemnum

힌트를 추가 할 수도 있습니다.+규칙/ 또는 /+주문/ 특히 오래된 버전에서는 어떤 일이 일어나는지 확인하기 위해 때때로 놀라운 결과를 얻을 수 있습니다.

SELECT /*+RULE*/
  c.ClaimNumber, a.ItemDate, c.DTN, b.FilePath
FROM
  items a,
  itempages b,
  keygroupdata c
WHERE a.ItemType IN (112,115,189,241)
  AND a.ItemNum = b.ItemNum
  AND b.ItemNum = c.ItemNum
ORDER BY a.DateStored DESC

쿼리 입력이 일정하거나 예측 가능한 경우 ( itemType IN (...)), 그러면 대안은 하루에 한두 번 쿼리를 실행하고 결과를 로컬 테이블에 저장하는 것입니다.

그런 다음 비용이 많이 드는 쿼리 '오프라인'을 만들고 대화식 쿼리에 대해 더 빠르고 더 나은 결과를 얻을 수 있습니다.

이것이 자주 실행되는 쿼리입니까? 이 쿼리 속도를 높이기 위해 필요한 색인을 작성하는 것이 DB 소유자의 관심사 인 것 같습니다. 쿼리를 실행하는 3.5 분은 생산 환경에 약간의 영향을 미쳐야합니다!

또한 테이블에서 업데이트 통계를 실행하고 있습니까? 결합 순서가 테이블의 통계에 따라 계산되므로 성능을 향상시킬 수 있습니다.

BTW, 당신은 무엇을 할 수 있습니까? 그냥 읽어? 임시 테이블을 만들고 인덱스를 넣을 수 있다면 테이블의 임시 사본을 만들고 인덱싱 한 다음 임시 사본과 인덱스 보조 조인을 수행하는 것을 고려할 수 있습니다.

이 스레드가 매우 오래된 것을 알고 있지만 검색 엔진의 경우 Oracle에서 작동하는 대체 솔루션을 제공하고 데이터에 따라 훨씬 빠를 수 있습니다.

with a as (
  select 
    * 
  from 
    items 
  where 
    ItemType IN (112,115,189,241)
)
SELECT 
  c.ClaimNumber
  , a.ItemDate
  , c.DTN, b.FilePath
FROM 
  a,
  itempages b,
  keygroupdata c
WHERE 
  a.ItemNum = b.ItemNum
  AND b.ItemNum = c.ItemNum
ORDER BY 
  a.DateStored DESC

당신은 또한 시도 할 수 있습니다 /*+ MATERIALIZE */ 힌트 WITH 절.

사실 나는 ANSI SQL보다 Oracle의 오래된 가입 구문을 읽는 것이 훨씬 쉽다는 것을 알았습니다 ^^

인덱싱이 없으면 테이블 크기가 증가함에 따라 해당 쿼리가 악화 될 것입니다. 그렇게 말하면, 절차별로 주문을 제거하고 클라이언트 측에서이를 수행하십시오.

때로는 WHERE 절에 중복 요소처럼 보이는 것을 추가하여 Optimizer가 선택할 수있는 추가 경로를 추가하여 이점을 볼 수 있습니다.

예를 들어, A.itemnum = B.itemnum 및 B.itemnum = C.itemnum이 있습니다. A.itemnum = C.itemnum도 추가하십시오. 그러나 나는 최적화가 자체적으로 그것을 알아낼 수있을 정도로 지능적이라고 확신합니다.

ItemType 열의 데이터 유형에 따라 Varchar 인 경우 다음을 사용하여 더 빠른 실행을 경험할 수 있습니다. Oracle은 변환을 암시합니다.

SELECT c.ClaimNumber, a.ItemDate, c.DTN, b.FilePath
FROM items a,
itempages b,
keygroupdata c
WHERE ((a.ItemType IN ('112','115','189','241'))
AND (a.ItemNum = b.ItemNum)
AND (b.ItemNum = c.ItemNum))
ORDER BY a.DateStored DESC

이 테이블에 통계가 수집됩니까? 그렇지 않다면 통계를 수집하면 실행 계획이 변경 될 수 있지만 반드시 더 나은 것은 아닙니다.

그 외에도 실행 계획을보십시오. 당신은 그것이 최적의 순서로 테이블을 결합하고 있음을 알 수 있습니다 (예 : 필터 조건이있는 A와 결합하기 전에 B와 C에 합류 할 수 있음).

힌트를 사용하여 액세스 경로에 영향을 미치거나 순서가 결합하거나 메소드를 결합시킬 수 있습니다.

업데이트: 댓글에 응답하면 나를 이끌었습니다 이것 도움이되거나 최소한 흥미로울 수있는 프레젠테이션.

인덱스가 없다고 말하면 이것은 기본 키나 외래 키가 정의되지 않았다는 것을 의미합니까? 분명히 테이블을 분석하고 통계를 수집하는 것이 중요하지만 테이블을 결합하는 방법을 정의하는 것과 같은 메타 데이터가 존재하지 않으면 Oracle은 실행 경로가 열악한 것을 선택할 수 있습니다.

이 경우 / *+ ordered * /와 같은 힌트를 사용하는 경우 Optimizer가 좋은 실행 경로를 안정적으로 선택할 수있는 유일한 옵션 일 수 있습니다. 외래 키와 기본 키를 추가하는 것이 좋습니다. 그러나 비활성화 및 검증으로 정의하십시오.

이 의견의 유용성은 인덱스에 대한 혐오가 얼마나 멀리 진행되는지에 달려 있다고 생각합니다.

먼저이 쿼리에서보기를 작성한 다음이 뷰에서 테이블을 생성하십시오. 또한 날짜에 인덱스를 만들고, 일자리를 만들고, 시스템이 유휴 상태 일 때 자정 시간에 일정을 잡으십시오.

글쎄, 인덱스를 만들 수 없으므로 통계가 모두 최신 상태인지 확인하고 쿼리를 이런 식으로 다시 작성해야합니다.

with a as (select /*+ MATERIALIZE */ ItemType, ItemNum, DateStored, ItemDate from items where ItemType in (112,115,189,241)) SELECT c.ClaimNumber, a.ItemDate, c.DTN, b.FilePath FROM a, itempages b, keygroupdata c WHERE a.ItemNum = b.ItemNum AND b.ItemNum = c.ItemNum ORDER BY a.DateStored DESC

주문을 제거하십시오

행을 응용 프로그램으로 다시 가져 오면 정렬을 수행하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top