1. 程式人生 > 實用技巧 >Oracle使用SPM優化指定SQL

Oracle使用SPM優化指定SQL

Oracle使用SPM優化指定SQL

環境構造

16:44:23 SYS@zkm(1)> drop table scott.zkm purge;

Table dropped.

Elapsed: 00:00:00.31
16:44:30 SYS@zkm(1)> create table scott.zkm as select * from dba_objects;

Table created.

Elapsed: 00:00:00.39
16:44:35 SYS@zkm(1)> create index scott.idx_object_id on scott.zkm(object_id) online;

Index created. Elapsed: 00:00:00.21

目標SQL

select /*+ full(a) */ * from scott.zkm a where object_id=1000;

由於hint的強制關係,該SQL會執行全表掃描,如下:

16:44:42 SYS@zkm(1)> set autotrace traceonly 
16:46:53 SYS@zkm(1)> set line 500
16:47:02 SYS@zkm(1)> select /*+ full(a) */ * from scott.zkm a where object_id=1000;

Elapsed: 
00:00:00.05 Execution Plan ---------------------------------------------------------- Plan hash value: 1571665327 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 207 | 366 (1)| 00:00:05 | |* 1 | TABLE ACCESS FULL| ZKM | 1 | 207 | 366 (1)| 00:00:05 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("OBJECT_ID"=1000) Note ----- - dynamic sampling used for this statement (level=2) Statistics ---------------------------------------------------------- 122 recursive calls 0 db block gets 1503 consistent gets 1603 physical reads 0 redo size 1628 bytes sent via SQL*Net to client 523 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 13 sorts (memory) 0 sorts (disk) 1 rows processed

新增基線,

col SQL_HANDLE for a25
col plan_name for a35
select signature,sql_handle,plan_name,origin,enabled,accepted,autopurge from dba_sql_plan_baselines;
模板複製

17:22:12 SYS@zkm(27)> col SQL_HANDLE for a25
17:22:21 SYS@zkm(27)> col plan_name for a35
17:22:26 SYS@zkm(27)> select signature,sql_handle,plan_name,origin,enabled,accepted,autopurge from dba_sql_plan_baselines;

 SIGNATURE SQL_HANDLE                PLAN_NAME                           ORIGIN                                     ENABLED   ACCEPTED  AUTOPURGE
---------- ------------------------- ----------------------------------- ------------------------------------------ --------- --------- ---------
8.8386E+18 SQL_7aa929320eda7c96      SQL_PLAN_7pa99687dnz4q45324a8c      MANUAL-LOAD                                YES       YES       YES

Elapsed: 00:00:00.00

可以檢視SQL_HANDLE='SQL_7aa929320eda7c96'且PLAN_NAME='SQL_PLAN_7pa99687dnz4q45324a8c'對應的執行計劃,

17:22:30 SYS@zkm(27)> select * from table(dbms_xplan.display_sql_plan_baseline(sql_handle=>'SQL_7aa929320eda7c96',plan_name=>'SQL_PLAN_7pa99687dnz4q45324a8c'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------
SQL handle: SQL_7aa929320eda7c96
SQL text: select /*+ full(a) */ * from scott.zkm a where object_id=1000
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
Plan name: SQL_PLAN_7pa99687dnz4q45324a8c         Plan id: 1160923788
Enabled: YES     Fixed: NO      Accepted: YES     Origin: MANUAL-LOAD
--------------------------------------------------------------------------------

Plan hash value: 1571665327

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  1097 |   221K|   366   (1)| 00:00:05 |
|*  1 |  TABLE ACCESS FULL| ZKM  |  1097 |   221K|   366   (1)| 00:00:05 |
--------------------------------------------------------------------------

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

   1 - filter("OBJECT_ID"=1000)

24 rows selected.

Elapsed: 00:00:00.07

若是庫快取中存在優秀的優秀的執行計劃,那麼直接找出plan hash value新增到SQL作為基線之一,然後刪除較差的sql的基線。

若是沒有優秀的執行計劃,可以手工使用hint產生你想要的執行計劃後,新增為基線,下邊演示這種。

新增hint強制走索引,

17:14:03 SYS@zkm(1)> select /*+ index(a idx_object_id) */ * from scott.zkm a where object_id=1000;

Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 3532417104

---------------------------------------------------------------------------------------------
| Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |               |     1 |   207 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| ZKM           |     1 |   207 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_OBJECT_ID |     1 |       |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

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

   2 - access("OBJECT_ID"=1000)

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
         27  recursive calls
          0  db block gets
         91  consistent gets
          1  physical reads
          0  redo size
       1631  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          4  sorts (memory)
          0  sorts (disk)
          1  rows processed

先查詢sql_id值,

col sql_id for a15
set line 500
col sql_text for a100
select sql_id,sql_text,PLAN_HASH_VALUE from v$sql where sql_text like 'select%from scott.zkm a where object_id=1000';
模板複製

17:44:56 SYS@zkm(27)> col sql_id for a15
17:45:03 SYS@zkm(27)> set line 500
17:45:07 SYS@zkm(27)> col sql_text for a100
17:45:10 SYS@zkm(27)> select sql_id,sql_text,PLAN_HASH_VALUE from v$sql where sql_text like 'select%from scott.zkm a where object_id=1000';

SQL_ID          SQL_TEXT                                                                                             PLAN_HASH_VALUE
--------------- ---------------------------------------------------------------------------------------------------- ---------------
9ajk015s54vpv   select /*+ full(a) */ * from scott.zkm a where object_id=1000                                             1571665327
7akf5qzu2f7wn   select /*+ index(a idx_object_id) */ * from scott.zkm a where object_id=1000                              3532417104

Elapsed: 00:00:00.00

將上邊執行路徑走了索引的執行計劃新增至

select /*+ full(a) */ * from scott.zkm a where object_id=1000;對應基線

中。

DECLARE
 k1 pls_integer;
begin
k1 := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (
sql_id=>'7akf5qzu2f7wn',
plan_hash_value=>3532417104,sql_handle=>'SQL_7aa929320eda7c96'
);
end;
/
模板複製
17:38:42 SYS@zkm(27)> DECLARE
17:39:00   2   k1 pls_integer;
17:39:00   3  begin
17:39:00   4  k1 := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE (
17:39:00   5  sql_id=>'7akf5qzu2f7wn',
17:39:00   6  plan_hash_value=>3532417104,sql_handle=>'SQL_7aa929320eda7c96'
17:39:00   7  );
17:39:00   8  end;
17:39:00   9  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01

17:47:46 SYS@zkm(1)> col SQL_HANDLE for a25
17:47:47 SYS@zkm(1)> col plan_name for a35
17:47:47 SYS@zkm(1)> select signature,sql_handle,plan_name,origin,enabled,accepted,autopurge from dba_sql_plan_baselines;

 SIGNATURE SQL_HANDLE                PLAN_NAME                           ORIGIN                                     ENABLED   ACCEPTED  AUTOPURGE
---------- ------------------------- ----------------------------------- ------------------------------------------ --------- --------- ---------
8.8386E+18 SQL_7aa929320eda7c96      SQL_PLAN_7pa99687dnz4q45324a8c      MANUAL-LOAD                                YES       YES       YES
8.8386E+18 SQL_7aa929320eda7c96      SQL_PLAN_7pa99687dnz4q54f02d62      MANUAL-LOAD                                YES       YES       YES

對應執行計劃,

17:47:47 SYS@zkm(1)> select * from table(dbms_xplan.display_sql_plan_baseline(sql_handle=>'SQL_7aa929320eda7c96',plan_name=>'SQL_PLAN_7pa99687dnz4q54f02d62'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------
SQL handle: SQL_7aa929320eda7c96
SQL text: select /*+ full(a) */ * from scott.zkm a where object_id=1000
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
Plan name: SQL_PLAN_7pa99687dnz4q54f02d62         Plan id: 1425026402
Enabled: YES     Fixed: NO      Accepted: YES     Origin: MANUAL-LOAD
--------------------------------------------------------------------------------

Plan hash value: 3532417104

---------------------------------------------------------------------------------------------
| Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |               |  1097 |   221K|     7   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| ZKM           |  1097 |   221K|     7   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_OBJECT_ID |   439 |       |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

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

   2 - access("OBJECT_ID"=1000)

25 rows selected.

Elapsed: 00:00:00.04

將原來的基線刪除,

17:49:14 SYS@zkm(1)> DECLARE
17:49:14   2   k1 pls_integer;
17:49:14   3  begin
17:49:14   4  k1 := DBMS_SPM.drop_sql_plan_baseline (  sql_handle=>'SQL_7aa929320eda7c96',plan_name=>'SQL_PLAN_7pa99687dnz4q45324a8c');
17:49:14   5  end;
17:49:14   6  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
17:49:14 SYS@zkm(1)> col SQL_HANDLE for a25
17:49:19 SYS@zkm(1)> col plan_name for a35
17:49:19 SYS@zkm(1)> select signature,sql_handle,plan_name,origin,enabled,accepted,autopurge from dba_sql_plan_baselines;

 SIGNATURE SQL_HANDLE                PLAN_NAME                           ORIGIN                                     ENABLED   ACCEPTED  AUTOPURGE
---------- ------------------------- ----------------------------------- ------------------------------------------ --------- --------- ---------
8.8386E+18 SQL_7aa929320eda7c96      SQL_PLAN_7pa99687dnz4q54f02d62      MANUAL-LOAD                                YES       YES       YES

Elapsed: 00:00:00.00

再次執行sql,已經走索引了。

17:50:01 SYS@zkm(1)> select /*+ full(a) */ * from scott.zkm a where object_id=1000;

Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 3532417104

---------------------------------------------------------------------------------------------
| Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |               |  1097 |   221K|     7   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| ZKM           |  1097 |   221K|     7   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_OBJECT_ID |   439 |       |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

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

   2 - access("OBJECT_ID"=1000)

Note
-----
   - SQL plan baseline "SQL_PLAN_7pa99687dnz4q54f02d62" used for this statement


Statistics
----------------------------------------------------------
         12  recursive calls
         10  db block gets
         78  consistent gets
          0  physical reads
          0  redo size
       1631  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

回退

把基線刪除即可。

參考

Oracle SQL執行計劃基線總結(SQL Plan Baseline)

Oracle如何固定執行計劃