设置autotrace的时候提示“Check PLUSTRACE role is enabled” 及使用QB_NAME hint

RDBMS 19.5.0.0.0

-- hr用户打开trace,提示错误 ,SYS用户授权给hr,也提示错误

HR@test>set autotrace trace on
SP2-0618: Cannot find the Session Identifier.  Check PLUSTRACE role is enabled
SP2-0611: Error enabling STATISTICS report
HR@test>

SYS@test>grant plustrace to hr;
grant plustrace to hr
      *
ERROR at line 1:
ORA-01919: role 'PLUSTRACE' does not exist


SYS@test>

官方文档对此的解释

https://docs.oracle.com/en/database/oracle/oracle-database/19/sqpug/SQL-Plus-error-messages.html#GUID-26D886EC-9FA3-4CFE-A017-1C913B7A7065

SP2-0618 Cannot find the Session Identifier. Check PLUSTRACE role is enabled Error enabling autotrace_report report
Cause: Unable to find the session identifier.

Action: Check that the PLUSTRACE role has been granted.


[oracle@redhat762100 admin]$ oerr sp2 0618
00618, 0, "Cannot find the Session Identifier.  Check PLUSTRACE role is enabled\n"
// *Cause:  Unable to find the session identifier.
// *Action: Check that the PLUSTRACE role has been granted.
[oracle@redhat762100 admin]$

官方文档中的解决方法:

https://docs.oracle.com/en/database/oracle/oracle-database/19/sqpug/tuning-SQL-Plus.html#GUID-1BA58F1E-2702-4104-8C2A-03DE008C6CBC

Example 8-2 Creating the PLUSTRACE Role

Run the following commands from your SQL*Plus session to create the PLUSTRACE role and grant it to the DBA:

CONNECT / AS SYSDBA 
@$ORACLE_HOME/sqlplus/admin/plustrce.sql 

drop role plustrace;

Role dropped.

create role plustrace;

Role created.

grant plustrace to dba with admin option;

Grant succeeded.

Example 8-3 Granting the PLUSTRACE Role

Run the following commands from your SQL*Plus session to grant the PLUSTRACE role to the HR user:

CONNECT / AS SYSDBA 
GRANT PLUSTRACE TO HR; 

Grant succeeded.

-- 执行脚本,过程如下

SYS@test>@?/sqlplus/admin/plustrce.sql
SYS@test>
SYS@test>drop role plustrace;
drop role plustrace
          *
ERROR at line 1:
ORA-01919: role 'PLUSTRACE' does not exist


SYS@test>create role plustrace;

Role created.

SYS@test>
SYS@test>grant select on v_$sesstat to plustrace;

Grant succeeded.

SYS@test>grant select on v_$statname to plustrace;

Grant succeeded.

SYS@test>grant select on v_$mystat to plustrace;

Grant succeeded.

SYS@test>grant plustrace to dba with admin option;

Grant succeeded.

SYS@test>
SYS@test>set echo off
SYS@test>

其实,这个脚本的内容很简单

[oracle@redhat762100 admin]$ more plustrce.sql
--
-- Copyright (c) Oracle Corporation 1995, 2002.  All Rights Reserved.
--
-- NAME
--   plustrce.sql
--
-- DESCRIPTION
--   Creates a role with access to Dynamic Performance Tables
--   for the SQL*Plus SET AUTOTRACE ... STATISTICS command.
--   After this script has been run, each user requiring access to
--   the AUTOTRACE feature should be granted the PLUSTRACE role by
--   the DBA.
--
-- USAGE
--   sqlplus "sys/knl_test7 as sysdba" @plustrce
--
--   Catalog.sql must have been run before this file is run.
--   This file must be run while connected to a DBA schema.

set echo on

drop role plustrace;
create role plustrace;

grant select on v_$sesstat to plustrace;
grant select on v_$statname to plustrace;
grant select on v_$mystat to plustrace;
grant plustrace to dba with admin option;

set echo off
[oracle@redhat762100 admin]$ ll

-- 授权成功

SYS@test>grant plustrace to hr;

Grant succeeded.

SYS@test>

-- 退出hr的session,重新登录即可

HR@test>set autotrace traceonly
HR@test>set linesize 120
HR@test>

对语句进行测试QB_NAME 提示

select /*+ full(@deptblock departments) */ employee_id from employees 
where employees.department_id in 
(select /*+ QB_NAME(deptblock) */ department_id
from departments 
where location_id=10);

关于QB_NAME提示的官方解释

https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/Comments.html#GUID-33072CBF-E61E-4A6D-A118-55290B8B6578

QB_NAME Hint

Description of qb_name_hint.eps follows
Description of the illustration qb_name_hint.eps

(See Specifying a Query Block in a Hint)

Use the QB_NAME hint to define a name for a query block. This name can then be used in a hint in the outer query or even in a hint in an inline view to affect query execution on the tables appearing in the named query block.

If two or more query blocks have the same name, or if the same query block is hinted twice with different names, then the optimizer ignores all the names and the hints referencing that query block. Query blocks that are not named using this hint have unique system-generated names. These names can be displayed in the plan table and can also be used in hints within the query block, or in query block hints. For example:

SELECT /*+ QB_NAME(qb) FULL(@qb e) */ employee_id, last_name
  FROM employees e
  WHERE last_name = 'Smith';

-- 在子查询中使用QB_NAME,查看执行计划,departments表,走了全扫描

HR@test>select /*+ full(@deptblock departments) */ employee_id from employees
w  2  here employees.department_id in
(s  3  elect /*+ QB_NAME(deptblock) */ department_id
  4  from departments
wh  5  ere location_id=10);

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 1021246405

--------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                   |     5 |    70 |     4   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                |                   |     5 |    70 |     4   (0)| 00:00:01 |
|   2 |   NESTED LOOPS               |                   |    10 |    70 |     4   (0)| 00:00:01 |
|*  3 |    TABLE ACCESS FULL         | DEPARTMENTS       |     1 |     7 |     3   (0)| 00:00:01 |
|*  4 |    INDEX RANGE SCAN          | EMP_DEPARTMENT_IX |    10 |       |     0   (0)| 00:00:01 |
|   5 |   TABLE ACCESS BY INDEX ROWID| EMPLOYEES         |    10 |    70 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

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

   3 - filter("LOCATION_ID"=10)
   4 - access("EMPLOYEES"."DEPARTMENT_ID"="DEPARTMENT_ID")


Statistics
----------------------------------------------------------
        182  recursive calls
          0  db block gets
        388  consistent gets
          0  physical reads
          0  redo size
        355  bytes sent via SQL*Net to client
        540  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
         18  sorts (memory)
          0  sorts (disk)
          0  rows processed

HR@test>

-- 全部去掉qb_name ,表departments走了索引  

select   employee_id from employees 
where employees.department_id in 
(select   department_id
from departments 
where location_id=10);

HR@test>select   employee_id from employees
w  2  here employees.department_id in
  3  (select   department_id
from d  4  epartments
wh  5  ere location_id=10);

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 2696597736

-----------------------------------------------------------------------------------------------------------
| Id  | Operation                             | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                      |                   |     5 |    70 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                         |                   |     5 |    70 |     3   (0)| 00:00:01 |
|   2 |   NESTED LOOPS                        |                   |    10 |    70 |     3   (0)| 00:00:01 |
|   3 |    TABLE ACCESS BY INDEX ROWID BATCHED| DEPARTMENTS       |     1 |     7 |     2   (0)| 00:00:01 |
|*  4 |     INDEX RANGE SCAN                  | DEPT_LOCATION_IX  |     1 |       |     1   (0)| 00:00:01 |
|*  5 |    INDEX RANGE SCAN                   | EMP_DEPARTMENT_IX |    10 |       |     0   (0)| 00:00:01 |
|   6 |   TABLE ACCESS BY INDEX ROWID         | EMPLOYEES         |    10 |    70 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------

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

   4 - access("LOCATION_ID"=10)
   5 - access("EMPLOYEES"."DEPARTMENT_ID"="DEPARTMENT_ID")


Statistics
----------------------------------------------------------
        202  recursive calls
          6  db block gets
        313  consistent gets
          1  physical reads
          0  redo size
        355  bytes sent via SQL*Net to client
        482  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
         21  sorts (memory)
          0  sorts (disk)
          0  rows processed

HR@test>

-- 如果子查询中不使用qb_name ,可以看到hint没有起作用,还是走的是索引,并没有按照提示走full 

select /*+ full(@deptblock departments) */ employee_id from employees 
where employees.department_id in 
(select department_id
from departments 
where location_id=10);

HR@test>select /*+ full(@deptblock departments) */ employee_id from employees
wh  2  ere employees.department_id in
  3  (select department_id
from  4   departments
whe  5  re location_id=10);

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 2696597736

-----------------------------------------------------------------------------------------------------------
| Id  | Operation                             | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                      |                   |     5 |    70 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                         |                   |     5 |    70 |     3   (0)| 00:00:01 |
|   2 |   NESTED LOOPS                        |                   |    10 |    70 |     3   (0)| 00:00:01 |
|   3 |    TABLE ACCESS BY INDEX ROWID BATCHED| DEPARTMENTS       |     1 |     7 |     2   (0)| 00:00:01 |
|*  4 |     INDEX RANGE SCAN                  | DEPT_LOCATION_IX  |     1 |       |     1   (0)| 00:00:01 |
|*  5 |    INDEX RANGE SCAN                   | EMP_DEPARTMENT_IX |    10 |       |     0   (0)| 00:00:01 |
|   6 |   TABLE ACCESS BY INDEX ROWID         | EMPLOYEES         |    10 |    70 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------

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

   4 - access("LOCATION_ID"=10)
   5 - access("EMPLOYEES"."DEPARTMENT_ID"="DEPARTMENT_ID")

Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 1 (N - Unresolved (1))
---------------------------------------------------------------------------

   0 -  DEPTBLOCK
         N -  full(@deptblock departments)


Statistics
----------------------------------------------------------
        197  recursive calls
          2  db block gets
        382  consistent gets
          0  physical reads
          0  redo size
        355  bytes sent via SQL*Net to client
        514  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
         18  sorts (memory)
          0  sorts (disk)
          0  rows processed

HR@test>

END 

发布了754 篇原创文章 · 获赞 31 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/xxzhaobb/article/details/103052677