문제

다음과 같은 SQL 쿼리가 있습니다.

SELECT * FROM(
    SELECT
        ...,
        row_number() OVER(ORDER BY ID) rn
    FROM
        ...
) WHERE rn between :start and :end

본질적으로 작업 속도를 늦추는 것은 ORDER BY 부분입니다.이를 제거하면 EXPLAIN 비용이 10배 이상(1000배 이상) 감소합니다.나는 이것을 시도했습니다 :

SELECT 
    ...
FROM
    ...
WHERE
    rownum between :start and :end

그러나 이것은 올바른 결과를 제공하지 않습니다.속도를 높이는 쉬운 방법이 있나요?아니면 EXPLAIN 도구를 사용하는 데 좀 더 시간을 투자해야 합니까?

도움이 되었습니까?

해결책

ROW_NUMBER 매우 비효율적입니다 Oracle.

성능 세부 정보는 내 블로그의 기사를 참조하십시오.

특정 쿼리를 위해서는이를 대체하는 것이 좋습니다. ROWNUM 인덱스가 사용되는지 확인하십시오.

SELECT  *
FROM    (
        SELECT  /*+ INDEX_ASC(t index_on_column) NOPARALLEL_INDEX(t index_on_column) */
                t.*, ROWNUM AS rn
        FROM    table t
        ORDER BY
                column
        )
WHERE rn >= :start
      AND rownum <= :end - :start + 1

이 쿼리는 사용됩니다 COUNT STOPKEY

또한 당신을 확인하십시오 column 무효가되지 않거나 추가합니다 WHERE column IS NOT NULL 상태.

그렇지 않으면 모든 값을 검색하는 데 인덱스를 사용할 수 없습니다.

사용할 수 없습니다 ROWNUM BETWEEN :start and :end 하위 퀘스트없이.

ROWNUM 항상 마지막으로 할당되어 마지막으로 확인됩니다. ROWNUM항상 틈없이 순서대로 나옵니다.

사용하는 경우 ROWNUM BETWEEN 10 and 20, 다른 모든 조건을 만족시키는 첫 번째 행은 일시적으로 할당 된 후보자가됩니다. ROWNUM = 1 그리고 시험에 실패합니다 ROWNUM BETWEEN 10 AND 20.

그러면 다음 행은 ROWNUM = 1 그리고 실패 등이 있으므로 마지막으로 줄은 전혀 반환되지 않습니다.

이것은 퍼팅을 통해 해결해야합니다 ROWNUM하위 쿼리에 있습니다.

다른 팁

나에게 페이지 매김 쿼리처럼 보입니다.

이 AskTom 기사에서 (페이지 아래로 약 90%) :

이 페이지 매김 쿼리에 고유 한 것으로 주문해야하므로 Row_number는 매번 행에 결정적으로 할당됩니다.

또한 귀하의 쿼리는 거의 동일하지 않으므로 다른 비용을 다른 비용과 비교할 수있는 이점이 확실하지 않습니다.

열별로 주문이 인덱싱 되었습니까? 그렇지 않다면 그것이 시작하기에 좋은 곳입니다.

문제의 일부는 '시작'부터 '끝'까지의 범위와 '살아 있는' 위치가 얼마나 큰지입니다.테이블에 백만 개의 행이 있고 567,890에서 567,900까지의 행을 원한다고 가정하면 전체 테이블을 통과해야 하며 거의 모든 것을 ID로 정렬해야 한다는 사실을 감수해야 합니다. 해당 범위에 어떤 행이 속하는지 알아보세요.

간단히 말해서, 작업량이 많기 때문에 옵티마이저가 높은 비용을 부과하는 것입니다.

또한 인덱스가 많은 도움을 줄 수 있는 것도 아닙니다.색인은 순서를 제공하지만 기껏해야 시작할 위치를 제공한 다음 567,900번째 항목에 도달할 때까지 계속 읽습니다.

한 번에 최종 사용자에게 10개의 항목을 표시하는 경우 실제로 DB에서 상위 100개 항목을 가져온 다음 앱이 해당 100개 항목을 10개의 청크로 나누도록 하는 것이 좋습니다.

설명 계획 도구로 더 많은 시간을 보내십시오. 테이블 스캔이 표시되면 쿼리를 변경해야합니다.

당신의 질문은 나에게 거의 의미가 없습니다. Rowid를 쿼리하는 것은 문제를 요구하는 것 같습니다. 해당 쿼리에는 관계형 정보가 없습니다. 문제가 발생한 실제 질문입니까, 아니면 문제를 설명하기 위해 구성한 예입니까?

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