如何在 Oracle 中收集扩展的查询执行统计信息?


问题

您想为特定查询收集扩展的解释计划统计信息。

解决方案

我们可以使用 GATHER_PLAN_STATISTICS 提示。此提示在运行时放置在查询中时,将生成扩展的运行时统计信息。它基本上有两个步骤。

  1. 使用 gather_plan_statistics 提示执行查询。
  2. 使用 dbms_xplan.display_cursor 显示结果。

示例

SELECT /*+ gather_plan_statistics */       city,       round(avg(fees)) avg_fees,       min(fees) min_fees,       max(fees) max_fees  FROM students e, departments d, locations l WHERE e.department_id = d.department_id   AND l.location_id = d.location_id GROUP BY city;

输出

Southlake   5760    4200    9000 Seattle     10701   6900    17000

现在我们将使用 dbms_xplan 显示扩展的查询统计信息。确保 SQL Plus 设置 SERVEROUTPUT 设置为 OFF,否则结果将无法正确显示。

示例

SELECT * FROM table(dbms_xplan.display_cursor(format=>'ALLSTATS LAST'));

SQL_ID  5cf72utppm8j1, child number 0 ------------------------------------- SELECT /*+ gather_plan_statistics */       city,       round(avg(fees)) avg_fees,        min(fees) min_fees,       max(fees) max_fees  FROM students e, departments d, locations l WHERE e.department_id = d.department_id   AND l.location_id = d.location_id GROUP BY city  

输出

Plan hash value: 1628862737
 
-------------------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name             | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT          |                  |      1 |        |      7 |00:00:00.01 |      22 |       |       |          |
|   1 |  HASH GROUP BY            |                  |      1 |     23 |      7 |00:00:00.01 |      22 |   851K|   851K| 1042K (0)|
|*  2 |   HASH JOIN               |                  |      1 |    106 |    106 |00:00:00.01 |      22 |  1610K|  1610K| 1416K (0)|
|*  3 |    HASH JOIN              |                  |      1 |     27 |     27 |00:00:00.01 |      16 |  1744K|  1744K| 1589K (0)|
|   4 |     VIEW                  | index$_join$_003 |      1 |     23 |     23 |00:00:00.01 |       8 |       |       |          |
|*  5 |      HASH JOIN            |                  |      1 |        |     23 |00:00:00.01 |       8 |  1449K|  1449K| 1625K (0)|
|   6 |       INDEX FAST FULL SCAN| LOC_CITY_IX      |      1 |     23 |     23 |00:00:00.01 |       4 |       |       |          |
|   7 |       INDEX FAST FULL SCAN| LOC_ID_PK        |      1 |     23 |     23 |00:00:00.01 |       4 |       |       |          |
|   8 |     VIEW                  | index$_join$_002 |      1 |     27 |     27 |00:00:00.01 |       8 |       |       |          |
|*  9 |      HASH JOIN            |                  |      1 |        |     27 |00:00:00.01 |       8 |  1610K|  1610K| 1535K (0)|
|  10 |       INDEX FAST FULL SCAN| DEPT_ID_PK       |      1 |     27 |     27 |00:00:00.01 |       4 |       |       |          |
|  11 |       INDEX FAST FULL SCAN| DEPT_LOCATION_IX |      1 |     27 |     27 |00:00:00.01 |       4 |       |       |          |
|  12 |    TABLE ACCESS FULL      | students        |      1 |    107 |    107 |00:00:00.01 |       6 |       |       |          |
-----------------------------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
   3 - access("L"."LOCATION_ID"="D"."LOCATION_ID")
   5 - access(ROWID=ROWID)
   9 - access(ROWID=ROWID)
 

注意:这是一个自适应计划

GATHER_PLAN_STATISTICS 提示收集运行时统计信息;因此需要执行查询才能收集这些统计信息。如果您已经有一个执行优化级别低于标准的查询,则可能需要使用 GATHER_PLAN_STATISTICS 提示运行您的查询。这可以快速为您提供普通解释计划中没有的信息,因为它显示了有关查询统计信息的估计和实际信息。F

收集这些额外的运行时统计信息确实需要一些资源。

数据准备:问题使用的数据如下所示。数据完全是为了演示目的而编造的。

示例

DROP TABLE students; COMMIT; CREATE TABLE students     ( student_id     NUMBER(6)     , first_name     VARCHAR2(20)     , last_name      VARCHAR2(25)     , email          VARCHAR2(40)     , phone_number   VARCHAR2(20)     , join_date      DATE     , class_id       VARCHAR2(20)       , fees           NUMBER(8,2)     , professor_id   NUMBER(6)     , department_id  NUMBER(4)     ) ;

示例

CREATE UNIQUE INDEX stu_id_pk ON students (student_id) ;
INSERT INTO students VALUES (100,'SMITH','JAMES','[email protected]','111.111.1245',TO_DATE('17-06-2003','DD-MM-YYYY'),'INS_CHAIRMAN',24000,NULL,NULL);
INSERT INTO students VALUES (101,'JOHNSON','JOHN','[email protected]','111.111.1246',TO_DATE('21-09-2005','DD-MM-YYYY'),'INS_VP',17000,100,90);
INSERT INTO students VALUES (102,'WILLIAMS','ROBERT','[email protected]','111.111.1247',TO_DATE('13-01-2001','DD-MM-YYYY'),'INS_VP',17000,100,90);
INSERT INTO students VALUES (103,'BROWN','MICHAEL','[email protected]','111.111.1248',TO_DATE('03-01-2006','DD-MM-YYYY'),'INS_STAFF',9000,102,60);
INSERT INTO students VALUES (104,'JONES','WILLIAM','[email protected]','111.111.1249',TO_DATE('21-05-2007','DD-MM-YYYY'),'INS_STAFF',6000,103,60);
INSERT INTO students VALUES (105,'MILLER','DAVID','[email protected]','111.111.1250',TO_DATE('25-06-2005','DD-MM-YYYY'),'INS_STAFF',4800,103,60);
INSERT INTO students VALUES (106,'DAVIS','RICHARD','[email protected]','111.111.1251',TO_DATE('05-02-2006','DD-MM-YYYY'),'INS_STAFF',4800,103,60);
INSERT INTO students VALUES (107,'GARCIA','CHARLES','[email protected]','111.111.1252',TO_DATE('07-02-2007','DD-MM-YYYY'),'INS_STAFF',4200,103,60);
INSERT INTO students VALUES (108,'RODRIGUEZ','JOSEPH','[email protected]','111.111.1253',TO_DATE('17-08-2002','DD-MM-YYYY'),'CL_PHY',12008,101,100);
INSERT INTO students VALUES (109,'WILSON','THOMAS','[email protected]','111.111.1254',TO_DATE('16-08-2002','DD-MM-YYYY'),'CL_MATH',9000,108,100);
INSERT INTO students VALUES (110,'MARTINEZ','CHRISTOPHER','[email protected]','111.111.1255',TO_DATE('28-09-2005','DD-MM-YYYY'),'CL_MATH',8200,108,100);
INSERT INTO students VALUES (111,'ANDERSON','DANIEL','[email protected]','111.111.1256',TO_DATE('30-09-2005','DD-MM-YYYY'),'CL_MATH',7700,108,100);
INSERT INTO students VALUES (112,'TAYLOR','PAUL','[email protected]','111.111.1257',TO_DATE('07-03-2006','DD-MM-YYYY'),'CL_MATH',7800,108,100);
INSERT INTO students VALUES (113,'THOMAS','MARK','[email protected]','111.111.1258',TO_DATE('07-12-2007','DD-MM-YYYY'),'CL_MATH',6900,108,100);

COMMIT;

示例

CREATE TABLE locations
    ( location_id    NUMBER(4)
    , street_address VARCHAR2(40)
    , postal_code    VARCHAR2(12)
    , city       VARCHAR2(30)
    CONSTRAINT     loc_city_nn  NOT NULL
    , state_province VARCHAR2(25)
    , country_id     CHAR(2)
    ) ;

示例

CREATE TABLE departments
    ( department_id    NUMBER(4)
    , department_name  VARCHAR2(30)
    CONSTRAINT  dept_name_nn  NOT NULL
    , professor_id       NUMBER(6)
    , location_id      NUMBER(4)
    ) ;

示例

INSERT INTO departments VALUES ( 10, 'Administration', 200, 1700);
INSERT INTO departments VALUES ( 20, 'Teaching', 201, 1800);                            
INSERT INTO departments VALUES ( 30  , 'Purchasing'  , 114   , 1700 );
INSERT INTO departments VALUES ( 40  , 'Human Resources'  , 203  , 2400  );
INSERT INTO departments VALUES ( 50  , 'Students'  , 121  , 1500  );
INSERT INTO departments VALUES ( 60   , 'IT'  , 103  , 1400  );
INSERT INTO departments VALUES ( 70   , 'Public Relations'  , 204  , 2700  );
INSERT INTO departments VALUES ( 80   , 'Fee collectors'  , 145  , 2500  );  
INSERT INTO departments VALUES ( 90   , 'Executive'  , 100  , 1700  );
INSERT INTO departments VALUES ( 100   , 'Finance'  , 108  , 1700  );  
INSERT INTO departments VALUES ( 110   , 'Accounting'  , 205  , 1700  );
INSERT INTO departments VALUES ( 120   , 'Treasury'  , NULL  , 1700  );
INSERT INTO departments VALUES ( 130   , 'Corporate Tax'  , NULL  , 1700  );
INSERT INTO departments VALUES ( 140   , 'Control And Credit'  , NULL  , 1700  );
INSERT INTO departments VALUES ( 160   , 'Benefits'  , NULL  , 1700  );
INSERT INTO departments VALUES ( 230   , 'Helpdesk'  , NULL  , 1700  );
COMMIT;

---------------------locations---------------

INSERT INTO locations VALUES ( 1000 , '1297 Via Cola di Rie' , '00989' , 'Roma' , NULL , 'IT' );
INSERT INTO locations VALUES ( 1100 , '93091 Calle della Testa' , '10934' , 'Venice' , NULL , 'IT' );
INSERT INTO locations VALUES ( 1200 , '2017 Shinjuku-ku' , '1689' , 'Tokyo' , 'Tokyo Prefecture' , 'JP' );
INSERT INTO locations VALUES ( 1300 , '9450 Kamiya-cho' , '6823' , 'Hiroshima' , NULL , 'JP' );
INSERT INTO locations VALUES ( 1400 , '2014 Jabberwocky Rd' , '26192' , 'Southlake' , 'Texas' , 'US' );
INSERT INTO locations VALUES ( 1500 , '2011 Interiors Blvd' , '99236' , 'South San Francisco' , 'California' , 'US' );
INSERT INTO locations VALUES ( 1600 , '2007 Zagora St' , '50090' , 'South Brunswick' , 'New Jersey' , 'US' );
INSERT INTO locations VALUES ( 1700 , '2004 Charade Rd' , '98199' , 'Seattle' , 'Washington' , 'US' );
INSERT INTO locations VALUES ( 1800 , '147 Spadina Ave' , 'M5V 2L7' , 'Toronto' , 'Ontario' , 'CA' );
INSERT INTO locations VALUES ( 1900 , '6092 Boxwood St' , 'YSW 9T2' , 'Whitehorse' , 'Yukon' , 'CA' );
INSERT INTO locations VALUES ( 2000 , '40-5-12 Laogianggen' , '190518' , 'Beijing' , NULL , 'CN' );
INSERT INTO locations VALUES ( 2100 , '1298 Vileparle (E)' , '490231' , 'Bombay' , 'Maharashtra' , 'IN' );
INSERT INTO locations VALUES ( 2200 , '12-98 Victoria Street' , '2901' , 'Sydney' , 'New South Wales' , 'AU' );
INSERT INTO locations VALUES ( 2300 , '198 Clementi North' , '540198' , 'Singapore' , NULL , 'SG' );
INSERT INTO locations VALUES ( 2400 , '8204 Arthur St' , NULL , 'London' , NULL , 'UK' );
INSERT INTO locations VALUES ( 2500 , 'Magdalen Centre, The Oxford Science Park' , 'OX9 9ZB' , 'Oxford' , 'Oxford' , 'UK' );
INSERT INTO locations VALUES ( 2600 , '9702 Chester Road' , '09629850293' , 'Stretford' , 'Manchester' , 'UK' );
INSERT INTO locations VALUES ( 2700 , 'Schwanthalerstr. 7031' , '80925' , 'Munich' , 'Bavaria' , 'DE' );
INSERT INTO locations VALUES ( 2800 , 'Rua Frei Caneca 1360 ' , '01307-002' , 'Sao Paulo' , 'Sao Paulo' , 'BR' );
INSERT INTO locations VALUES ( 2900 , '20 Rue des Corps-Saints' , '1730' , 'Geneva' , 'Geneve' , 'CH' );
INSERT INTO locations VALUES ( 3000 , 'Murtenstrasse 921' , '3095' , 'Bern' , 'BE' , 'CH' );
INSERT INTO locations VALUES ( 3100 , 'Pieter Breughelstraat 837' , '3029SK' , 'Utrecht' , 'Utrecht' , 'NL' );
INSERT INTO locations VALUES ( 3200 , 'Mariano Escobedo 9991' , '11932' , 'Mexico City' , 'Distrito Federal,' , 'MX' );
COMMIT;

更新于: 2020-12-05

412 次查看

启动您的 职业生涯

通过完成课程获得认证

开始
广告