쿼리의 설명 계획을 어떻게 해석합니까?


88

SQL 문이 실행되는 방식을 이해하려고 할 때 때때로 Explain 계획을 살펴 보는 것이 좋습니다. 계획 설명을 해석 (이치) 할 때 거쳐야하는 프로세스는 무엇입니까? "아, 이거 훌륭하게 작동하고있어?"라는 점이 눈에 띄어 야합니다. 대 "오, 그렇지 않아요."

답변:


80

전체 테이블 스캔이 나쁘고 인덱스 액세스가 좋다는 의견을 볼 때마다 떨립니다. 전체 테이블 스캔, 인덱스 범위 스캔, 빠른 전체 인덱스 스캔, 중첩 루프, 병합 조인, 해시 조인 등은 분석가가 이해하고 데이터베이스 구조 및 쿼리 목적에 대한 지식과 결합되어야하는 단순한 액세스 메커니즘입니다. 의미있는 결론에 도달하기 위해

전체 스캔은 데이터 세그먼트 (테이블 또는 테이블 (하위) 파티션)의 많은 블록을 읽는 가장 효율적인 방법이며, 종종 성능 문제를 나타낼 수 있지만 컨텍스트에서만 발생합니다. 쿼리의 목표를 달성하기위한 효율적인 메커니즘인지 여부. 데이터웨어 하우스 및 BI 담당자라고 말하면 성능에 대한 가장 큰 경고 플래그는 인덱스 기반 액세스 방법과 중첩 루프입니다.

따라서 계획 설명을 읽는 방법의 메커니즘에 대해서는 Oracle 설명서가 좋은 가이드입니다. http://download.oracle.com/docs/cd/B28359_01/server.111/b28274/ex_plan.htm#PFGRF009

Performance Tuning Guide도 잘 읽으십시오.

또한 쿼리의 다양한 단계에서 카디널리티 추정치를 실행 중에 경험 한 실제 카디널리티와 비교하는 데 계획 설명을 사용할 수있는 기술인 "카디널리티 피드백"에 대한 Google도 있습니다. 볼프강 브라 이틀 링이이 방법의 저자라고 믿습니다.

따라서 결론은 액세스 메커니즘을 이해하는 것입니다. 데이터베이스를 이해하십시오. 쿼리의 의도를 이해합니다. 경험 법칙을 피하십시오.


5
처음 9 개의 단어 이후에 당신이라는 것을 알았습니다. "name that tune"과 같습니다 ... n 단어 이하로 Dave A 게시물을 식별 할 수 있습니다 ...

"large"사용에 대해 약간 의문을 제기 할 것입니다 ... 때로는 데이터가 인덱스 열 주변에 너무 열악하게 클러스터링되어 FTS가 행의 10 %조차도 인덱스 스캔을 수행 할 수 있습니다 ...

1
10 %-절대적으로. 블록 당 200 개의 행이 있고 행의 0.5 %를 찾고 있다면 이론적으로 모든 값을 얻기 위해 블록의 100 %에 액세스해야 할 수 있으므로 10 %보다 훨씬 더 극단적이됩니다.
David Aldridge


5

아래의 두 가지 예는 INDEX를 사용하는 FULL 스캔과 FAST 스캔을 보여줍니다.

비용과 카디널리티에 집중하는 것이 가장 좋습니다. 예를 살펴보면 인덱스를 사용하면 쿼리 실행 비용이 절감됩니다.

조금 더 복잡하지만 (그리고 100 % 처리 할 수 ​​없습니다) 기본적으로 비용은 CPU 및 IO 비용의 함수이고 카디널리티는 Oracle이 구문 분석 할 것으로 예상하는 행 수입니다. 이 두 가지를 모두 줄이는 것은 좋은 일입니다.

쿼리 비용은 쿼리 및 Oracle 옵티 마이저 모델 (예 : COST, CHOOSE 등) 및 통계 실행 빈도에 의해 영향을받을 수 있음을 잊지 마십시오.

예 1 :

SCAN http://docs.google.com/a/shanghainetwork.org/File?id=dd8xj6nh_7fj3cr8dx_b

인덱스를 사용하는 예 2 :

INDEX http://docs.google.com/a/fukuoka-now.com/File?id=dd8xj6nh_9fhsqvxcp_b

그리고 이미 제안했듯이 TABLE SCAN을주의하십시오. 일반적으로이를 피할 수 있습니다.


어, 룰 모드는 비용이 들지 않습니다 ... 그래서 당신의 진술은 가장 절대적인 방식으로 정확하다고 생각하지만 근본적으로 부정확하다고 말할 것입니다. CHOOSE라고하면 RBO 또는 CBO를받을 수 있습니다. CBO는 비용을 계산하는 유일한 회사입니다.

4

순차 스캔과 같은 것을 찾는 것은 다소 유용 할 수 있지만 현실은 숫자에 있습니다. 일반적으로 쿼리 계획 을 보는 것보다 훨씬 더 유용한 것은 실제 실행을 보는 것 입니다. Postgres에서 이것은 EXPLAIN과 EXPLAIN ANALYZE의 차이점입니다. EXPLAIN ANALYZE는 실제로 쿼리를 실행하고 모든 노드에 대한 실제 타이밍 정보를 가져옵니다. 그러면 플래너가 생각하는 것 대신 실제로 일어나는 일 을 볼 수 있습니다. 가 일어날 것 . 여러 번 순차 스캔이 전혀 문제가 아니라 쿼리에서 다른 문제라는 것을 알게 될 것입니다.

다른 핵심은 실제 비용이 많이 드는 단계를 식별하는 것입니다. 많은 그래픽 도구는 다른 크기의 화살표를 사용하여 계획 비용의 다른 부분을 나타냅니다. 이 경우 얇은 화살표가 들어오고 두꺼운 화살표가 나가는 단계를 찾으십시오. GUI를 사용하지 않는 경우 숫자를 주시하고 갑자기 훨씬 커지는 부분을 찾아야합니다. 약간의 연습으로 문제 영역을 선택하는 것이 상당히 쉬워집니다.


3

실제로 이러한 문제에 대해 가장 좋은 방법은 ASKTOM입니다. 입니다. 특히이 질문에 대한 그의 답변에는 온라인 Oracle 문서에 대한 링크가 포함되어 있으며 여기에서 이러한 종류의 규칙이 많이 설명되어 있습니다.

명심해야 할 한 가지는 계획 설명이 정말 최선의 추측이라는 것입니다.

sqlplus 사용법을 배우고 AUTOTRACE 명령으로 실험하는 것이 좋습니다. 일부 어려운 숫자를 사용하면 일반적으로 더 나은 결정을 내릴 수 있습니다.

하지만 물어봐야합니다. 그는 그것에 대해 모두 알고 있습니다 :)


2

Explain의 출력은 각 단계에 걸린 시간을 알려줍니다. 첫 번째는 오랜 시간이 걸린 단계를 찾아 그 의미를 이해하는 것입니다. 순차 스캔과 같은 것은 더 나은 인덱스가 필요하다는 것을 알려줍니다. 이는 대부분 특정 데이터베이스와 경험에 대한 연구의 문제입니다.


2

하나의 "오, 그건 옳지 않습니다"는 종종 테이블 스캔 의 형태입니다 . 테이블 스캔은 특별한 인덱스를 사용하지 않으며 메모리 캐시에서 유용한 모든 것을 제거하는 데 기여할 수 있습니다. 예를 들어 postgreSQL에서는 다음과 같이 보입니다.

Seq Scan on my_table  (cost=0.00..15558.92 rows=620092 width=78)

때로는 테이블 스캔이 인덱스를 사용하여 행을 쿼리하는 것보다 이상적입니다. 그러나 이것은 당신이 찾고있는 것처럼 보이는 붉은 깃발 패턴 중 하나입니다.


2
(전체) 테이블 스캔이 반드시 메모리 캐시를 제거하지는 않습니다.
a_horse_with_no_name

2

기본적으로 각 작업을 살펴보고 작업이 어떻게 작동해야하는지에 대한 지식을 바탕으로 작업이 "합리적"인지 확인합니다.

예를 들어 각각의 열 C와 D (AC = BD)에서 두 개의 테이블 A와 B를 조인하고 계획에 테이블에 클러스터형 인덱스 스캔 (SQL Server 용어-오라클 용어가 확실하지 않음)이 표시되는 경우 A, 그런 다음 일련의 클러스터형 인덱스에 대한 중첩 루프 조인이 테이블 B에서 검색하면 문제가 있다고 생각할 수 있습니다. 이 시나리오에서는 엔진이 병합 조인이 뒤 따르는 인덱스 스캔 쌍 (조인 된 열의 인덱스에 대해)을 수행 할 것으로 예상 할 수 있습니다. 추가 조사를 통해 옵티마이 저가 해당 조인 패턴 또는 실제로 존재하지 않는 인덱스를 선택하도록하는 잘못된 통계가 밝혀 질 수 있습니다.


1

계획의 각 하위 섹션에서 소요 된 시간의 백분율을보고 엔진이 수행하는 작업을 고려하십시오. 예를 들어 테이블을 스캔하는 경우 스캔중인 필드에 인덱스를 추가하는 것이 좋습니다.


1

주로 인덱스 또는 테이블 스캔을 찾습니다. 이것은 일반적으로 where 문 또는 join 문에있는 중요한 열에 인덱스가 없음을 나타냅니다.

에서 http://www.sql-server-performance.com/tips/query_execution_plan_analysis_p1.aspx :

실행 계획에 다음 중 하나가 표시되면 경고 신호를 고려하여 잠재적 인 성능 문제를 조사해야합니다. 각각은 성능 측면에서 이상적이지 않습니다.

* Index or table scans: May indicate a need for better or  additional indexes.
* Bookmark Lookups: Consider changing the current clustered index,
  consider using a covering index, limit
  the number of columns in the SELECT
  statement.
* Filter: Remove any functions in the WHERE clause, don't include wiews
  in your Transact-SQL code, may need
  additional indexes.
* Sort: Does the data really need to be sorted? Can an index be used to
  avoid sorting? Can sorting be done at
  the client more efficiently? 

항상 피할 수있는 것은 아니지만 더 많이 피할수록 쿼리 성능이 빨라집니다.


1
테이블 스캔이 모두 나쁘지는 않습니다. 테이블에서 반환 / 처리 된 레코드 수에 따라 전체 테이블 스캔이 인덱스 스캔보다 빠를 수 있습니다 (어쨌든 레코드를 다시 가져 오려는 경우 인덱스 스캔을 수행합니다. 테이블에서 전체 읽기-1 대신 2 단계).
ScottCher

-7

경험의 규칙

(자세한 내용도 읽어보고 싶을 것입니다.

나쁜

여러 대형 테이블의 테이블 스캔

좋은

고유 인덱스 사용
색인에는 모든 필수 필드가 포함됩니다.

가장 일반적인 승리

내가 본 성능 문제의 약 90 %에서 가장 쉬운 방법은 테이블이 많은 (4 개 이상) 많은 쿼리를 2 개의 작은 쿼리와 임시 테이블로 나누는 것입니다.


2
테이블 스캔은 너무 자주 나쁜 것으로 간주되며 처음에는 경험이없는 사람들이 집중하는 것입니다. 이는 해당 테이블에서 반환되는 레코드 수에 따라 크게 달라지며 인덱스 조회보다 전체 테이블 스캔을 더 빠르게 수행 할 수있는 임계 값이 있습니다.
ScottCher

8
터무니없는 조언에 찬성했습니다. 성능 문제의 90 %는 임시 테이블과 쿼리 분할로 해결되지 않습니다. 당신은 어떤 세계에 살고 있습니까?!
TheSoftwareJedi

@Jedi, 저는 indeces가 대부분 옳고 데이터베이스가 현명하게 구조화 된 세상에 살고 있습니다. 그래도 대답을 읽고 싶습니다.
AJ.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.