programing

GATER_PLAN_STATISTICS가 기본 계획 통계를 생성하지 않습니다.

abcjava 2023. 8. 14. 22:23
반응형

GATER_PLAN_STATISTICS가 기본 계획 통계를 생성하지 않습니다.

모든.

다음을 실행했을 때 쿼리를 조정하는 방법을 배우고 있습니다.

select /*+ gather_plan_statistics */ * from emp;

select * from table(dbms_xplan.display(FORMAT=>'ALLSTATS LAST'));

결과는 항상 다음과 같습니다.

  • 경고: 기본 계획 통계를 사용할 수 없습니다.다음과 같은 경우에만 수집됩니다.
    • hint 'https_plan_statistics'는 문장 또는
    • 매개 변수 'statistics_level'이 세션 또는 시스템 수준에서 'ALL'로 설정되었습니다.

해봤습니다.alter session set statistics_level = ALL;sqlplus에서도 마찬가지이지만 결과는 바뀌지 않았습니다.

제가 무엇을 놓쳤을 수도 있는지 알려주실 수 있나요?

정말 감사합니다.

DISPLAY Function은 EXPLE PLAN FOR 명령으로 생성된(채움) PLAN_TABLE의 내용을 표시합니다.따라서 EXPLE PLAN FOR 명령을 사용하여 다음과 같은 방법으로 (이론적) 계획을 생성하고 표시할 수 있습니다.

create table emp as select * from all_objects;

explain plan for
select /*+ gather_plan_statistics */ count(*) from emp where object_id between 100 and 150;

select * from table(dbms_xplan.display );

Plan hash value: 2083865914

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |     5 |   351   (1)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |     5 |            |          |
|*  2 |   TABLE ACCESS FULL| EMP  |    12 |    60 |   351   (1)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("OBJECT_ID"<=150 AND "OBJECT_ID">=100)

gather_plan_statistics */ hint는 데이터를 PLAN_TABLE에 저장하지 않지만 실행 통계를 V$SQL_PLAN 성능 보기에 저장합니다.
이러한 데이터를 표시하려면 여기에 설명된 방법인 http://www.dba-oracle.com/t_gather_plan_statistics.htm, 을 사용할 수 있지만 SQL 쿼리 직후에 두 번째 명령을 실행해야 하기 때문에 항상 작동하는 것은 아닙니다.

더 나은 방법은 V$SQL 보기를 쿼리하여 쿼리의 SQL_ID를 얻은 다음 DISPLAY_CURSOR 함수를 사용하는 것입니다. 예를 들어 다음과 같습니다.

select /*+ gather_plan_statistics */ count(*) from emp where object_id between 100 and 150;

select sql_id, plan_hash_value, child_number, executions, fetches, cpu_time, elapsed_time, physical_read_requests, physical_read_bytes
from v$sql s
where sql_fulltext like 'select /*+ gather_plan_statistics */ count(*)%from emp%'
  and sql_fulltext not like '%from v$sql' ;

SQL_ID        PLAN_HASH_VALUE CHILD_NUMBER EXECUTIONS    FETCHES   CPU_TIME ELAPSED_TIME PHYSICAL_READ_REQUESTS PHYSICAL_READ_BYTES
------------- --------------- ------------ ---------- ---------- ---------- ------------ ---------------------- -------------------
9jjm288hx7buz      2083865914            0          1          1      15625        46984                     26            10305536

위의 쿼리가 반환됩니다.SQL_ID=9jjm288hx7buz그리고.CHILD_NUMBER=0(자녀 번호는 커서 번호일 뿐입니다.)다음 값을 사용하여 콜링된 계획을 쿼리합니다.

SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR('9jjm288hx7buz', 0, 'ALLSTATS'));

SQL_ID  9jjm288hx7buz, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ count(*) from emp where object_id 
between 100 and 150

Plan hash value: 2083865914

-------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      2 |        |      2 |00:00:00.05 |   10080 |
|   1 |  SORT AGGREGATE    |      |      2 |      1 |      2 |00:00:00.05 |   10080 |
|*  2 |   TABLE ACCESS FULL| EMP  |      2 |     47 |     24 |00:00:00.05 |   10080 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter(("OBJECT_ID"<=150 AND "OBJECT_ID">=100))

실행한 것이 질문에 포함된 두 개의 문장뿐인 경우:

select /*+ gather_plan_statistics */ * from emp;

select * from table(dbms_xplan.display(FORMAT=>'ALLSTATS LAST'));

그렇다면 당신의 문제는 당신이 사용하는 것이라고 생각합니다.DBMS_XPLAN.DISPLAY사용 방법은 마지막으로 실행한 문이 아니라 마지막으로 설명한 문의 계획을 인쇄하는 것입니다.그리고 "설명"은 쿼리를 실행하지 않기 때문에 다음과 같은 이점을 얻을 수 없습니다.gather_plan_statistics넌지시 비추다

이것은 12c에서 작동합니다.

select /*+ gather_plan_statistics */ count(*) from dba_objects;

SELECT *
FROM   TABLE (DBMS_XPLAN.display_cursor (null, null, 'ALLSTATS LAST'));

예.,display_cursor의 대신에display.

지금까지 답변을 통해 배운 것은 다음과 같습니다.

쿼리가 구문 분석되면 최적화 도구는 쿼리 계획의 각 단계에서 생성되는 행 수를 추정합니다.때때로 예측이 얼마나 좋았는지 확인할 필요가 있습니다.추정치가 몇 자릿수 이상 차이가 나면 잘못된 계획이 사용될 수 있습니다.

추정된 숫자와 실제 숫자를 비교하려면 다음 단계가 필요합니다.

  1. 다음에 대한 읽기 권한이 필요합니다.V$SQL_PLAN,V$SESSION그리고.V$SQL_PLAN_STATISTICS_ALL은 이한권에있다습에 되어 있습니다.SELECT_CATALOG역할. (소스)

  2. 다음을 기준으로 통계 수집 켜기

    ALTER SESSION SET STATISTICS_LEVEL = ALL;

    해서./*+ gather_plan_statistics */

    오버헤드가 있는 것 같습니다.예를 들어 조나단의 블로그를 참조하십시오.

  3. 쿼리를 실행합니다.나중에 찾아야 하므로 임의 힌트를 포함하는 것이 좋습니다.

    SELECT /*+ gather_plan_statistics HelloAgain */ * FROM scott.emp;

    EXPLAIN PLAN FOR SELECT ...실제 쿼리를 실행하지 않고 견적만 생성하므로 충분하지 않습니다.

    또한, @Mathew가 제안한 것처럼 (감사합니다!) 모든 행을 실제로 가져오는 것이 중요합니다.대부분의 GUI는 처음 50개 정도의 행만 표시합니다.SQL Developer에서 쿼리 결과 창에서 바로 가기 ctrl+End를 사용할 수 있습니다.

  4. 쿼리를 "" " " " " 입니다.SQL_ID:

    SELECT sql_id, child_number, sql_text FROM V$SQL WHERE sql_text LIKE '%HelloAgain%';

    dbqbqxp9srftn 0 SELECT /*+ gather_plan...

  5. 결과 형식 지정:

    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('dbqbqxp9srftn',0,'ALLSTATS LAST'));

4단계와 5단계를 결합할 수 있습니다.

SELECT x.* 
  FROM v$sql s, 
       TABLE(DBMS_XPLAN.DISPLAY_CURSOR(s.sql_id, s.child_number)) x 
 WHERE s.sql_text LIKE '%HelloAgain%';

결과는 추정된 행을 보여줍니다(E-Rows) 및 실제 행(A-Rows):

SQL_ID  dbqbqxp9srftn, child number 0
-------------------------------------
SELECT /*+ gather_plan_statistics HelloAgain */ * FROM scott.emp

Plan hash value: 3956160932

------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |     14 |00:00:00.01 |       6 |
|   1 |  TABLE ACCESS FULL| EMP  |      1 |     14 |     14 |00:00:00.01 |       6 |
------------------------------------------------------------------------------------

ALLSTATS LAST는 문을 두 번 실행한 후에 작동하기 시작합니다.

언급URL : https://stackoverflow.com/questions/32823223/gather-plan-statistics-does-does-not-generate-basic-plan-statistics

반응형