如何查看通过 Statspack 捕获的 Amazon RDS Oracle 数据库实例的执行计划?
上次更新时间:2020 年 3 月 13 日
我使用 Statspack 捕获了我的 Amazon Relational Database Service (Amazon RDS) Oracle 数据库实例的性能统计数据。但是,该 Statspack 报告中没有任何与执行计划相关的信息。我该如何查看通过 Statspack 捕获的查询执行计划?
解决方案
1. 拍摄一张快照级别大于或等于 6 (i_snap_level => 6) 的 Statspack 快照,以捕获 SQL 执行计划。有关跟你更多信息,请参阅如何检查运行 Oracle 的 Amazon RDS 数据库实例的性能统计数据?
2. 使用 Statspack 报告确认开始快照 ID、结束快照 ID 和查询的旧哈希值。在以下示例中,开始快照 ID 为 22,结束快照 ID 为 23:
STATSPACK report for
Database DB Id Instance Inst Num Startup Time Release RAC
~~~~~~~~ ----------- ------------ -------- --------------- ----------- ---
1234567890 silent 1 03-Jan-20 00:45 12.2.0.1.0 NO
Host Name Platform CPUs Cores Sockets Memory (G)
~~~~ ---------------- ---------------------- ----- ----- ------- ------------
ip-172-31-22-176 Linux x86 64-bit 2 2 1 3.7
Snapshot Snap Id Snap Time Sessions Curs/Sess Comment
~~~~~~~~ ---------- ------------------ -------- --------- ------------------
Begin Snap: 22 03-Jan-20 01:30:36 41 .8
End Snap: 23 03-Jan-20 01:39:12 40 .8
Elapsed: 8.60 (mins) Av Act Sess: 0.0
DB time: 0.11 (mins) DB CPU: 0.11 (mins)
...
3. 使用旧哈希值查找查询,以查看执行计划。Statspack 报告包括不同的“SQL 排序依据”部分。例如,“按 CPU DB/Inst 对 SQL 排序”部分列出了大量占用 CPU 的查询。以下示例使用旧哈希值 73250552,这是那个时候大多数大量占用 CPU 的查询的哈希值:
...
SQL ordered by CPU DB/Inst: SILENT/silent Snaps: 22-23
-> Total DB CPU (s): 7
-> Captured SQL accounts for 80.3% of Total DB CPU
-> SQL reported below exceeded 1.0% of Total DB CPU
CPU CPU per Elapsd Old
Time (s) Executions Exec (s) %Total Time (s) Buffer Gets Hash Value
---------- ------------ ---------- ------ ---------- --------------- ----------
4.03 3 1.34 60.8 4.08 528,477 73250552
Module: SQL*Plus
SELECT COUNT(*) FROM HOGE_TBL H1 INNER JOIN HOGE_TBL H2 USING(OB
JECT_NAME)
0.75 1 0.75 11.3 0.77 18,994 2912400228
Module: sqlplus@ip-172-31-22-176 (TNS V1-V3)
BEGIN statspack.snap; END;
0.14 107 0.00 2.1 0.15 732 3879834072
select TIME_WAITED_MICRO from V$SYSTEM_EVENT where event = 'Sha
red IO Pool Memory'
...
3. 使用 Oracle 客户端连接到数据库实例,如 SQL*Plus。
4. 调用与以下内容相似的查询,以检索执行计划:
SELECT lpad(' ', 1 * ( depth - 1 ))
|| operation AS operation,
object_name,
cardinality,
bytes,
cost
FROM stats$sql_plan
WHERE plan_hash_value IN(SELECT plan_hash_value
FROM stats$sql_plan_usage
WHERE old_hash_value = OLD_HASH_VALUE
AND snap_id BETWEEN BEGIN_SNAP_ID AND END_SNAP_ID
AND plan_hash_value > 0)
ORDER BY plan_hash_value, id;
注意:请将 OLD_HASH_VALUE、BEGIN_SNAP_ID 和 END_SNAP_ID 替换为您自己的值。
以下示例是 SQL*Plus 检索的查询的执行计划:
SQL> col operation format a20
col object_name format a20
SQL>SELECT lpad(' ', 1 * ( depth - 1 ))
|| operation AS operation,
object_name,
cardinality,
bytes,
cost
FROM stats$sql_plan
WHERE plan_hash_value IN(SELECT plan_hash_value
FROM stats$sql_plan_usage
WHERE old_hash_value = 73250552
AND snap_id BETWEEN 22 AND 23
AND plan_hash_value > 0)
OPERATION OBJECT_NAME CARDINALITY BYTES COST
-------------------- -------------------- ----------- ---------- ----------
SELECT STATEMENT 1119
SORT 1 70
HASH JOIN 87756 6142920 1119
TABLE ACCESS HOGE_TBL 72992 2554720 397
TABLE ACCESS HOGE_TBL 72992 2554720 397