申明:本文非原创,翻译整理自https://expertoracle.com/中的十六篇文章,后文给出了原文的出处。
一、选择性和基数
1、选择性:
- 它代表操作筛选的行的分数,因此可以说它是唯一性的度量。
- 它的值在 0 和 1 之间
- 如果你的查询返回 100 行然后你放置一个过滤器(例如“where”条件)使最终结果仅为 10 那么你的选择性是 0.1(10/100)或者你可以还说你的选择性是 10%
- 在另一个例子中,如果你的查询返回 200 行,即使在放置过滤器之后最终结果也是 200,那么你的选择性是 1 或 100%。这被称为不良选择性。它是“坏的”,因为所有的记录都来了。
- 如果 SQL 返回少量重复行,则列具有高度选择性。这被称为良好的选择性。
- 如果 SQL 返回全部或大量行,则列的选择性最低。这称为 BAD 选择性。
当运行 SELECT * FROM EMP 并且不提供任何过滤器时,选择性将自动为 1,因为将返回所有行。
添加复合索引是使 BAD 选择性变为 GOOD 选择性的最佳方法。使用多个列会使索引更加独特,从而提高索引的选择性。
2、基数
操作返回的行数是基数。选择性和基数之间的关系如下:
基数 = 选择性 × 输入行数
假设的查询从数据库中获得了 200 条记录,并通过放置一些过滤器等使最终行数为 50,因此你的选择性变为 0.25 (50/200),基数为 50 (200 * 0.25)。
有时 Oracle 优化器无法预测给定运算符将返回的行数(因为缺少表统计信息等原因)。这会阻止 Oracle 正确估计查询计划的成本,从而导致选择次优计划。基数估计错误会导致查询运行缓慢。
现在让我们看一些例子:
- 假设你有一个名为 EMP 的表,其中有 10 条记录。你想知道此表中最大的 EMP_NUMBER。
SELECT MAX(EMP_NUMBER) from EMP;
选择性 = 访问的行数/总行数 = 10/10 = 1(100% 的行被访问)
基数 = 访问的行数 = 10
- 现在假设你将过滤器放在 LAST_NAME 列的 SQL 查询中
SELECT MAX(EMP_NUMBER) from EMP where LAST_NAME='SMITH';
假设只有 4 名员工姓氏为“SMITH”
选择性 = 访问的行数/总行数 = 4/10 = 0.4(访问了 40% 的行)
基数 = 访问的行数 = 4
二、解析
1、解析步骤
- 验证语法
- 验证语句中引用的对象
- 分配给执行作业的用户的权限
- 验证语句是否已在共享池中可用。Oracle 引擎会计算 SQL 语句的哈希值并查找
- 如果语句不存在则分配共享内存并在共享池中创建游标
- 生成执行计划
2、解析类型
HARD PARSE:这意味着该语句在共享内存中不可用,或者这是用户正在尝试执行的全新语句。如果你的共享池很小,则可能还需要硬解析,因为旧语句已从共享池中老化。上面提到的所有解析步骤都需要针对这种情况进行。硬解析需要额外的系统资源。这也称为“库缓存未命中”。
SOFT PARSE:这意味着该语句较早执行并且已经被解析并且在内存中可用。因此 Oracle 只需要执行上面提到的步骤 1-3,因为其他任务之前已经完成。就好比一次努力,多次收获。这也称为“库缓存命中”,因为你已解析语句并可在库缓存中使用。
还有一个soft soft parse,表示会话复用会话内的子游标
3、为什么应该避免硬解析
硬解析应保持在最低限度的要求有两个主要原因:
1、执行计划的生成是一个非常占用 CPU 的操作。
2、共享池中的内存是有限的,内存操作也是序列化的。内存操作使用共享池锁存器进行,如果发生如此多的硬解析,则数据库中的其他进程将不得不在队列中等待以获取共享池锁存器。因此,硬解析会影响共享池锁存器和库缓存锁存器的数量。
三、父游标和子游标
游标”是library cache中的一块内存区域,分配给用户执行的SQL语句。该内存区域存储有关 SQL 语句的关键信息,如 SQL 文本、SQL 执行计划、统计信息等。
每条SQL语句都有一个父游标和一个或多个子游标。让我们了解什么是父游标和子游标。
请记住 Cursor = Memory Area
1、为什么有两种游标?
这是由 Oracle 数据库设计的,你有两种游标:父游标和子游标。对于你执行的每条 SQL 语句,Oracle 引擎都会生成两个游标:父游标和子游标。生成两个游标是因为对于同一个 SQL 语句,可能存在其他差异,例如可能存在不同的绑定值或两个不同的schema或不同的文字值等。父游标将保存 SQL 语句,子游标保存的信息与差异有关。这实质上使子游标成为 SQL 语句将进行硬解析还是软解析的决定因素。
2、父游标
它存储游标的 SQL 文本。当两个语句逐字相同时,它们将共享相同的父 Cursor。
每个父游标都将与至少一个为其创建的子游标一起执行。
父游标在视图 V$SQLAREA 中表示。v$sqlarea 中的 VERSION_COUNT 列可以告诉我们这个父游标有多少个子游标。
3、子游标
- 每个父项至少有一个子游标,也可以有多个子游标
- 父游标存储 SQL 文本,子游标存储与 SQL 语句相关的其他重要信息,例如:环境详细信息、统计信息详细信息、绑定变量详细信息、执行计划详细信息绑定变量详细信息。
- 子游标占用较少的内存空间,因为 SQL 文本不存储在子游标中
- 每个子游标都必须属于一个父游标
- 子游标决定查询是进行硬解析还是软解析。你可能会发现 SQL 查询对于两个语句相同的情况,因此父游标相同但子游标不可共享到 SQL 进行硬解析(重新编译)。
- 父游标在视图 V$SQL 中表示
- V$SQL_SHARED_CURSOR 是一个非常有用的视图,因为它提供了优化器决定将游标标记为非共享的原因。因此,无论何时你看到 SQL 语句相同但仍然发生硬解析,请查看此视图。
4、V$SQL_SHARED_CURSOR
此视图解释了为什么特定子游标不与现有子游标共享,这导致为同一父游标创建多个子游标。此视图中的每一列标识无法共享游标的特定原因。这些列用“Y”或“N”作为值来描述各种原因。你应该关注值为“Y”的列。一个特定的孩子可能由于多种原因而未能共享 - 即:尝试使用不同的现有子游标的不同原因。
以下脚本为mos提供用于查询子游标不共享原因
select * from
(select sql_id, nonshared_reason, count(*) from v$sql_shared_cursor
unpivot
(nonshared_value for nonshared_reason in (
UNBOUND_CURSOR as 'UNBOUND_CURSOR',
SQL_TYPE_MISMATCH as 'SQL_TYPE_MISMATCH',
OPTIMIZER_MISMATCH as 'OPTIMIZER_MISMATCH',
OUTLINE_MISMATCH as 'OUTLINE_MISMATCH',
STATS_ROW_MISMATCH as 'STATS_ROW_MISMATCH',
LITERAL_MISMATCH as 'LITERAL_MISMATCH',
FORCE_HARD_PARSE as 'FORCE_HARD_PARSE',
EXPLAIN_PLAN_CURSOR as 'EXPLAIN_PLAN_CURSOR',
BUFFERED_DML_MISMATCH as 'BUFFERED_DML_MISMATCH',
PDML_ENV_MISMATCH as 'PDML_ENV_MISMATCH',
INST_DRTLD_MISMATCH as 'INST_DRTLD_MISMATCH',
SLAVE_QC_MISMATCH as 'SLAVE_QC_MISMATCH',
TYPECHECK_MISMATCH as 'TYPECHECK_MISMATCH',
AUTH_CHECK_MISMATCH as 'AUTH_CHECK_MISMATCH',
BIND_MISMATCH as 'BIND_MISMATCH',
DESCRIBE_MISMATCH as 'DESCRIBE_MISMATCH',
LANGUAGE_MISMATCH as 'LANGUAGE_MISMATCH',
TRANSLATION_MISMATCH as 'TRANSLATION_MISMATCH',
BIND_EQUIV_FAILURE as 'BIND_EQUIV_FAILURE',
INSUFF_PRIVS as 'INSUFF_PRIVS',
INSUFF_PRIVS_REM as 'INSUFF_PRIVS_REM',
REMOTE_TRANS_MISMATCH as 'REMOTE_TRANS_MISMATCH',
LOGMINER_SESSION_MISMATCH as 'LOGMINER_SESSION_MISMATCH',
INCOMP_LTRL_MISMATCH as 'INCOMP_LTRL_MISMATCH',
OVERLAP_TIME_MISMATCH as 'OVERLAP_TIME_MISMATCH',
EDITION_MISMATCH as 'EDITION_MISMATCH',
MV_QUERY_GEN_MISMATCH as 'MV_QUERY_GEN_MISMATCH',
USER_BIND_PEEK_MISMATCH as 'USER_BIND_PEEK_MISMATCH',
TYPCHK_DEP_MISMATCH as 'TYPCHK_DEP_MISMATCH',
NO_TRIGGER_MISMATCH as 'NO_TRIGGER_MISMATCH',
FLASHBACK_CURSOR as 'FLASHBACK_CURSOR',
ANYDATA_TRANSFORMATION as 'ANYDATA_TRANSFORMATION',
PDDL_ENV_MISMATCH as 'PDDL_ENV_MISMATCH',
TOP_LEVEL_RPI_CURSOR as 'TOP_LEVEL_RPI_CURSOR',
DIFFERENT_LONG_LENGTH as 'DIFFERENT_LONG_LENGTH',
LOGICAL_STANDBY_APPLY as 'LOGICAL_STANDBY_APPLY',
DIFF_CALL_DURN as 'DIFF_CALL_DURN',
BIND_UACS_DIFF as 'BIND_UACS_DIFF',
PLSQL_CMP_SWITCHS_DIFF as 'PLSQL_CMP_SWITCHS_DIFF',
CURSOR_PARTS_MISMATCH as 'CURSOR_PARTS_MISMATCH',
STB_OBJECT_MISMATCH as 'STB_OBJECT_MISMATCH',
CROSSEDITION_TRIGGER_MISMATCH as 'CROSSEDITION_TRIGGER_MISMATCH',
PQ_SLAVE_MISMATCH as 'PQ_SLAVE_MISMATCH',
TOP_LEVEL_DDL_MISMATCH as 'TOP_LEVEL_DDL_MISMATCH',
MULTI_PX_MISMATCH as 'MULTI_PX_MISMATCH',
BIND_PEEKED_PQ_MISMATCH as 'BIND_PEEKED_PQ_MISMATCH',
MV_REWRITE_MISMATCH as 'MV_REWRITE_MISMATCH',
ROLL_INVALID_MISMATCH as 'ROLL_INVALID_MISMATCH',
OPTIMIZER_MODE_MISMATCH as 'OPTIMIZER_MODE_MISMATCH',
PX_MISMATCH as 'PX_MISMATCH',
MV_STALEOBJ_MISMATCH as 'MV_STALEOBJ_MISMATCH',
FLASHBACK_TABLE_MISMATCH as 'FLASHBACK_TABLE_MISMATCH',
LITREP_COMP_MISMATCH as 'LITREP_COMP_MISMATCH',
PLSQL_DEBUG as 'PLSQL_DEBUG',
LOAD_OPTIMIZER_STATS as 'LOAD_OPTIMIZER_STATS',
ACL_MISMATCH as 'ACL_MISMATCH',
FLASHBACK_ARCHIVE_MISMATCH as 'FLASHBACK_ARCHIVE_MISMATCH',
LOCK_USER_SCHEMA_FAILED as 'LOCK_USER_SCHEMA_FAILED',
REMOTE_MAPPING_MISMATCH as 'REMOTE_MAPPING_MISMATCH',
LOAD_RUNTIME_HEAP_FAILED as 'LOAD_RUNTIME_HEAP_FAILED',
HASH_MATCH_FAILED as 'HASH_MATCH_FAILED',
PURGED_CURSOR as 'PURGED_CURSOR',
BIND_LENGTH_UPGRADEABLE as 'BIND_LENGTH_UPGRADEABLE',
USE_FEEDBACK_STATS as 'USE_FEEDBACK_STATS'
))
where nonshared_value = 'Y'
group by sql_id, nonshared_reason
)
where sql_id = '&sqlid' ;
5、cursor_sharing 数据库参数的概念
-
EXACT
只允许具有相同文本的语句共享同一个游标。 -
FORCE
强制在某些文字上可能不同但在其他方面相同的语句共享游标,除非文字影响语句的含义。 -
SIMILAR
导致某些文字可能不同但其他方面相同的语句共享游标,除非文字影响语句的含义或计划优化的程度。
默认的 cursor_sharing 条件是 EXACT,这意味着每个不同的 SQL 语句都会创建一个新的父游标。生产中请不要随意更改该参数,保持exact就好。
四、绑定变量
绑定变量通常被认为是提高 SQL 查询性能的关键特性之一。根据 Oracle 文档绑定变量是 SQL 语句中的占位符,必须用有效值或值地址替换该语句才能成功执行。通过使用绑定变量,可以编写在运行时接受输入或参数的 SQL 语句。
你可以将 SQL 查询视为任何编程语言中的一种“函数”,并将绑定变量视为你传递给该函数的“值”。
绑定变量在 OLTP 类型的环境中特别重要,因为使用绑定变量可以实现软解析,这意味着在选择优化的执行计划上花费的处理时间更少。
你可以使用 VARIABLE 命令在 SQL*Plus 中创建绑定变量
1、优点
因此,如果我们必须列出使用绑定变量的主要好处,那么这些将是:
-
1.更好的共享池利用率:Oracle 共享池必须只保存一个语句而不是可能非常多的语句。
-
- No Hard Parsing so Better performance : 对于只有值不同的SQL语句不需要硬解析。
-
- 减少“库缓存”闩锁争用:绑定变量有助于避免每次需要硬解析时发生的库缓存闩锁争用导致的性能问题。
2、缺点
现在谈到使用绑定变量的缺点。请注意,在许多情况下,绑定变量将被证明对于提高数据库性能非常有用,但有时它可能会产生负面结果。绑定变量可以减少为(Cost Based Optimizer)CBO 计算最优访问路径的信息
由于绑定值的使用,CBO 可能无法确定真正的选择性并产生错误的执行计划。它可能会进行全表扫描,因为可以使用索引。有时,Oracle CBO 需要 SQL 将使用的字面值来创建更好的执行计划。SInce 绑定变量“隐藏”了文字值,因此 CBO 可能会创建次优计划。为了应对这种情况,Oracle 试图通过允许 CBO 在创建执行计划时“窥视”绑定变量的值来帮助 CBO。这给我们带来了另一个术语“绑定变量窥视”。
3、Bind Variable Peeking(绑定变量窥视)
这是一种 Oracle 方法,在生成执行计划之前,CBO 会查看绑定变量的值并将它们用作生成更好的执行计划的文字。这种方法的漏洞是生成的执行计划取决于第一次执行提供的值。请注意,根据 where 条件中提供的值,有时需要全表扫描,而在其他时间需要使用索引。由于绑定变量查看是基于第一次执行提供的值,因此这种方法有时也会产生错误的执行计划。为了解决这个问题,oracle通过“自适应光标共享”向软件中添加了更多的智能。
4、自适应游标共享
此功能从 Oracle 11g 开始可用。在这种方法中,Oracle CBO 不会盲目地使用游标,即使它有次优计划(就像它曾经在使用绑定变量查看时发生的那样)而是识别何时重新使用已经可用的游标会导致 SQL 执行效率低下. 如果使用 Adaptive Cursor Sharing 的 CBO 发现现有计划无法证明有效,那么它将生成另一个具有不同执行计划的子游标。
总而言之,绑定变量的使用在 OLTP 类环境中确实有助于提高性能,但在使用绑定变量时必须非常小心,因为有时它可能不是解决性能问题的灵丹妙药,甚至会降低性能。
五、跟踪和TKPROF(一)
1、追踪
跟踪文件是由 Oracle 数据库生成的一组原始数据。可以说跟踪是 Oracle 的一项功能,可以启用该功能以在执行程序时生成包含内部SQL活动的原始文本文件。
跟踪 SQL 活动时获得的内部活动包含每个语句的以下统计信息:
- 解析、执行和获取计数
- CPU 和运行时间
- 物理读和逻辑读
- 处理的行数
- 库缓存未命中
- 每次解析发生的用户名
- 每次提交和回滚
2、TKPROF
TKPROF 重新格式化跟踪文件中存在的原始数据,以便更容易查看报告。tkprof不控制跟踪文件的内容。tkprof对于详细的跟踪文件分析很有价值。
分析tkprof 文件时有两个基本目标:
- 找出花费最多时间的 SQL/操作
- 找出占用最高资源的 SQL/操作。
3、与TRACE相关的关键数据库初始化参数
在进行跟踪之前,为了使跟踪信息完整,需要设置以下几个参数。
- TIMED_STATISTICS:此参数必须设置为 TRUE。
- MAX_DUMP_FILE_SIZE :应该足够大以允许文件被完全写入。最好设置 max_dump_file_size=UNLIMITED。
- STATISTICS_LEVEL:应设置为 ALL,也可以设置成typical,但是采集的信息会少点
跟踪级别
默认情况下,应使用级别8带等待)。然后可以通过等待(例如物理 I/O、锁定/争用、用户操作等)来分析经过时间的原因。
级别12还提供绑定变量信息,这在某些情况下很有用(如果需要谓词和过滤器中使用的值)。但是,这会增加大量开销并产生更大的文件,尤其是在有大量执行(或较少执行的批量绑定)和/或大量绑定变量的情况下。所以只有在需要绑定时才使用级别 12。考虑到绑定值中还可能包含安全或敏感数据。
其他级别是
Level1:标准 SQL Trace
- 级别 4:包括绑定变量
- 级别 16 – 每次执行都将 STAT 行写入跟踪文件(相当于 plan_stat=ALL_EXECUTIONS)
- 级别 32 – 从不将行源统计信息(STAT 行)写入跟踪文件(相当于 plan_stat=NEVER)
- 级别 64 – 行源统计信息(STAT 行)针对 SQL 语句消耗的每分钟 DB 时间写入跟踪文件(相当于 plan_stat=ADAPTIVE)(仅限 11.2.0.2/补丁 8328200)。
- 级别 8(带等待)是默认选择,因为它给出了每个 SQL 的等待事件统计信息(等待次数、最长等待时间和总等待时间)。
如果需要绑定值,则在第12级获取跟踪(使用绑定和等待)。但是,这会增加大量开销并产生更大的文件,尤其是在有大量执行(或较少执行的批量绑定)和/或大量绑定变量的情况下。
5、父/子跟踪
为了减少经过的时间,一些批处理进程使用多个子进程。例如在 EBS 应用程序的情况下
父并发请求可能会产生多个子请求。
补丁和升级上使用的自动补丁(adpatch)和在线补丁(adop)工具可以使用多个worker(AD Workers)。
请注意,所有children/workers可能不会进行相同的活动,并且工作量可能不会平均分配。因此,在这种情况下,理想情况下,所有子SQL跟踪文件或辅助SQL跟踪文件都应与任何父 SQL 跟踪文件一起获取。至少需要对父项和一些子项(表现出性能问题)进行SQL跟踪。
6、跟踪文件位置
SELECT value FROM V$DIAG_INFO WHERE NAME = 'Diag Trace';
7、跟踪文件命名约定
跟踪文件名通常是
<实例>ora
8、SQL_TRACE
SQL_TRACE是Oracle中收集SQL执行信息的主要方法。它记录了可用于调整SQL操作的各种信息和统计信息。
会话级别的跟踪
也可以通过发出以下SQL语句在系统/会话中启用/禁用 SQL_TRACE:
ALTER SESSION SET SQL_TRACE = TRUE/FALSE;
在 11g 及更高版本中,sql_trace 也是一个事件,可以使用事件语法进行设置
alter session set events 'sql_trace bind=true';
alter session set events 'sql_trace bind=true, wait=true';
在 SQL_ID 级别进行跟踪
在 Oracle 11.1 及更高版本中,可以通过指定过滤器将跟踪限制为特定的 SQL ID:
ALTER SYSTEM SET EVENTS sql_trace [sql: sql_id=4k1jlmn567cr7] bind=true, wait=true';
可以使用 | 指定多个 SQL ID 作为分隔符的符号:
ALTER SYSTEM SET EVENTS sql_trace [sql: sql_id=5t6ygtsa3d356|6fa43fgg0rrtp] bind=true, wait=true';
在数据库级别进行跟踪
可以使用初始化参数 SQL_TRACE 在实例级别设置 SQL_TRACE:
TRUE – 启用为所有会话收集统计信息。
FALSE – 禁止为所有会话收集统计信息。
ALTER SYSTEM SET SQL_TRACE = TRUE/FALSE;
9、10046 TRACE EVENT
10046 是特殊的 EVENT 代码。10046 跟踪等同于设置 SQL_TRACE=TRUE。使用事件的优点是可以根据事件指定的级别将额外的详细信息输出到跟踪文件。
10046 EVENT 级别与前面讨论的相同:1、4、8、16、32、64。
会话级别:
alter session set events '10046 trace name context forever'; <= LEVEL 1 BASIC TRACE
alter session set events '10046 trace name context forever, level 8'; <= LEVEL 8 (WAITS) TRACE)
alter session set events '10046 trace name context forever,level 12'; <= LEVEL 12 (BINDS & WAITS) TRACE
alter session set events '10046 trace name context off'; <= 关闭跟踪
alter system set events '10046 trace name context forever,level 12';
alter system set events '10046 trace name context off';
event="10046 trace name context forever,level 4"
请注意,通常我们不会在数据库级别执行此操作,因为它会跟踪所有数据库会话,这可能会给数据库和文件系统带来巨大的开销。系统范围的 10046 跟踪对于已知发生问题会话但无法提前识别的情况可能很有用。在这种情况下,可以在短时间内启用跟踪,然后可以重现问题并禁用跟踪,并在生成的跟踪中搜索问题的证据
10、自动跟踪
autotrace 命令用于查看 SQL*Plus 会话中 SQL 语句的执行计划和一些有用的统计信息。
SQL> set autotrace traceonly explain
SQL> select * from EMP;
11、使用DBMS_MONITOR/DBMS_SESSION 进行跟踪
使用 DBMS_MONITOR 可以根据指定的客户端标识符或服务名称、模块名称和操作名称的分层组合启用跟踪。也可以在会话级别启用跟踪。
对客户端标识符或服务/模块/操作的跟踪在会话断开连接和数据库关闭期间是持久的,并且可以应用于所有实例。跟踪将保持启用状态,直到使用 DBMS_MONITOR 禁用为止。
SESSION_TRACE_ENABLE
SESSION_TRACE_ENABLE 为本地实例上的给定数据库会话启用 SQL 跟踪。
exec dbms_monitor.session_trace_enable(session_id => x, serial_num => y, waits=>(TRUE|FALSE),binds=>(TRUE|FALSE) );
exec dbms_monitor.session_trace_disable(session_id => x, serial_num => y);
等待的默认值为 TRUE,绑定的默认值为 FALSE。当会话断开或执行上述命令时,跟踪将停止。
DBMS_SESSION 也可用于轻松跟踪任何数据库会话。尽管 DBMS_MONITOR 包只能由具有 DBA 角色的用户调用,但用户还可以通过调用 DBMS_SESSION.SESSION_TRACE_ENABLE 过程为自己的会话启用 SQL 跟踪
- 以 system 或 sys 用户登录数据库 SQL*Plus。
- 从用户的 v$session 表中找出 serial#、session id 并运行以下命令开始跟踪
exec dbms_session.set_sql_trace_in_session(sid, seria#, TRUE);
- 让用户执行需要跟踪的必要操作。
- 使用以下命令禁用跟踪:
exec dbms_session.set_sql_trace_in_session(sid, seria#, FALSE);
- 这将在数据库的跟踪目录中生成一个.trc 文件。
CLIENT_ID_TRACE_ENABLE
在多层环境中,来自终端客户端的请求由中间层路由到不同的数据库会话。这意味着终端客户端和数据库会话之间的关联是非静态的。在 10g 版本之前,没有简单的方法来跟踪不同数据库会话中的客户端。端到端跟踪通过引入新属性 CLIENT_IDENTIFIER 使这成为可能,该属性唯一标识给定的最终客户端。客户端标识符在 V$SESSION 的 CLIENT_IDENTIFIER 列中可见。它也可以通过系统上下文看到。
dbms_monitor.client_id_trace_enable ( client_id =>'client_id', waits => (TRUE|FALSE), binds => (TRUE|FALSE) );
dbms_monitor.client_id_trace_disable ( client_id =>'client_id');
将跟踪文件与 TRCSESS 组合
一些跟踪操作会产生多个跟踪文件。trcsess 实用程序对于合并 sql_trace / 10046 文件并最终将它们提供给 tkprof 实用程序进行处理非常有用。它是在 Oracle 10g 中引入的。TRCSESS 根据某些会话或客户端标识符组合跟踪文件。
trcsess [output=<输出文件名>] [session=<session ID>] [clientid=<clientid>] [service=<service name>] [action=<action name>] [module=<module name>] <跟踪文件名>
可以在 DBA_ENABLED_TRACES 中跟踪确定哪些属性启用了跟踪的方法。
select trace_type, primary_id, QUALIFIER_ID1, waits, binds from DBA_ENABLED_TRACES;
12、ORADEBUG
oradebug 是一个优秀的实用程序,可以在进程启动后对其进行跟踪。如果需要从正在运行的会话进行跟踪,则可以使用 oradebug 附加到会话并启动 10046 跟踪。
以下是使用 oradebug 实用程序的步骤:
- 识别需要跟踪的会话的 PID/SPID
select v$process p,v$session s from p.PID,p.SPID,s.SID where s.paddr = p.addr and s.sid = &SESSION_ID;
SPID : 操作系统进程标识符 (ospid)
PID : Oracle 进程标识符 (orapid)
- 使用 oradebug 应用跟踪
connect / as sysdba
oradebug setospid <SPID>
oradebug unlimit
oradebug event 10046 trace name context forever,level 12
connect / as sysdba
oradebug setorapid <PID>
oradebug unlimit
oradebug event 10046 trace name context forever,level 12
- 跟踪完成后禁用 oradebug 跟踪
oradebug event 10046 trace name context off
13、使用触发器在用户级别进行跟踪
CREATE OR REPLACE TRIGGER SYS.set_trace
AFTER LOGON ON DATABASE
WHEN (USER like '&USERNAME')
DECLARE
lcommand varchar(200);
BEGIN
EXECUTE IMMEDIATE 'alter session set tracefile_identifier=''From_Trigger''';
EXECUTE IMMEDIATE 'alter session set statistics_level=ALL';
EXECUTE IMMEDIATE 'alter session set max_dump_file_size=UNLIMITED';
EXECUTE IMMEDIATE 'alter session set events ''10046 trace name context forever, level 12''';
END set_trace;
/
14、需要牢记的几点要点
- 很多时候跟踪文件会变得很大并填满文件系统,从而导致不良问题。密切关注跟踪过程并始终删除过时的跟踪/tkprof 文件。
- 仅对出现问题的会话 (SID) 启用跟踪。
- 为跟踪文件保留一些合理的名称,以便你可以轻松识别它。
六、跟踪和 TKPROF(二)
1、TKPROF 文件包含什么:
- 执行的SQL 文本
- 计时信息:执行计数、运行时间、CPU 时间、物理读取(磁盘)、逻辑读取(查询/当前)以及每个 SQL 返回的行数。这进一步细分为解析、执行和获取阶段。
- 等待信息:每个数据库等待事件的等待次数、最大等待时间和总等待时间,包括每个 SQL 和整个跟踪期间。它仅在级别为 8(等待)或 12(等待和绑定)时执行此操作。建议至少使用 8 级,因为它提供了额外的信息。
- 执行计划: 每个 SQL 的运行时执行计划以及每个执行计划行的实际行源操作计数。只有当 SQL 的游标已关闭(在 10g 及更早版本中)或 SQL 的行源统计信息已写入跟踪时,它才会执行此操作。如果 SQL 使用视图或同义词,执行计划还将包含实际访问的表。
它还包含诸如库缓存未命中(硬解析)和总 SQL 以及递归和非递归 SQL 语句的等待统计信息等信息
2、如何从跟踪文件生成 TKPROF 文件
以下是从跟踪文件生成 TKPROF 文件的典型命令:
tkprof <文件名1> <文件名2> sort= fchela,exeela,prsela sys=no
在将跟踪的 SQL 语句列在输出文件中之前,按指定排序选项的降序对跟踪的 SQL 语句进行排序。如果指定了多个选项,则输出按排序选项中指定的值的总和降序排序。如果你省略此参数,则 TKPROF 会按照首次使用的顺序将语句列到输出文件中。
我们发现 sort= fchela,exeela,prsela 选项在解决性能问题方面最有效。
排序选项如下:
PRSCNT – 解析次数
PRSCPU – 解析花费的 CPU 时间
PRSELA – 解析花费的时间
PRSDSK – 解析期间从磁盘物理读取的次数
PRSQRY – 解析期间读取一致模式块的次数
PRSCU – 解析期间读取当前模式块的次数
PRSMIS –解析期间库缓存未命中数
EXECNT –执行次数
EXECPU –执行CPU时间执行期间块读取
EXEROW – 执行期间处理的行数
EXEMIS – 执行期间库缓存未命中数FCHNT –获取次数
FCHCPU – 获取获取所花费的 CPU 时间
FCHELA – 获取所花费的已用时间获取期间当前模式块读取
FCHROW – 获取的行数
USERID – 解析游标的用户的用户 ID
注意:虽然使用这些选项在大多数情况下会有所帮助,但有时使用未排序的 tkprof 会很有用。SQL 以它们被解析的顺序列出。因此,这有时可以帮助找到导致问题的代码部分,或者帮助确定跟踪是否被禁用(在 tkprof 结束时)。
3、使用 TKPROF 的示例
- 正常 TKPROF
tkprof 跟踪文件 输出文件
- 带排序的 TKPROF
如果你正在使用 SORT 参数和 PRINT 参数的组合处理大型跟踪文件,那么你可以生成仅包含最高资源密集型语句的 TKPROF 输出文件。例如,以下语句打印跟踪文件中产生最多物理 I/O 的 10 个语句:
TKPROF oracle_123.trc oracle_123.out SORT=PRSDSK、EXEDSK、FCHDSK PRINT = 10
- 带有排序和解释选项的 TKPROF
TKPROF <跟踪文件> <输出文件> explain=user/password@service table=sys.plan_table
- 带有排序和解释选项但没有“SYS”组件的 TKPROF
TKPROF <trace-file> <output-file> explain=user/password@service table=sys.plan_table SYS=NO
4、需要记住的几个要点
- 为了创建 tkprof 文件,你必须在创建文件的目录中具有写入权限。如果你在跟踪目录中没有写入权限,则指定你有写入权限的目录。
- 请使用 RDBMS Oracle Home /bin 目录下的 TKPROF。Applications Oracle Home 下的 TKPROF 不会产生准确的结果。
七、跟踪和TKPROF(三)
1、TKPROF 文件的部分
每个 tkprof 输出文件都可以大致分为标题、主体和摘要部分。
- HEADER:显示跟踪文件名、定义和选择的排序选项。
- BODY:包含 SQL 语句的性能指标。
- SUMMARY:包含文件中所有 SQL 语句的性能统计信息的集合。
2、标题部分
每个 TKPROF 报告都以列出以下信息的标头开头:
- TKPROF 版本
- 生成报告的日期和时间
- 跟踪文件的名称
- 使用的排序选项
- 报告中列标题的简要定义。
标头部分中的大部分信息是静态信息。
3、正文部分
TKPROF 报告的主体由启用 SQL 跟踪时执行的每个不同 SQL 语句的条目组成。让我们从正文部分看一下 tkprof 的这样一个部分,首先定义 TKPORF 文件中使用的基本术语. TKPROF 将为在该会话中运行的每个 SQL 包含许多这样的部分。TKPROF 报告中每个 SQL 语句的条目由一行星号分隔。
kprof 主体输出的总体结构是:
- SQL语句
- 解析/执行/获取统计信息和时间
- 库缓存信息
- 行源计划
- 语句等待的事件
4、摘要部分
请注意 tkprof 的最后一行,上面写着“跟踪文件中经过的秒数”。这是一个关键参数,当你分析 tkprof 文件以了解整个跟踪文件操作花费了多长时间时,你应该看到该参数。这些数据将告诉你将要处理的问题有多大。
5、分析 TKPROF 时要记住的要点
- 识别不使用绑定变量的 SQL 语句。通过使用绑定变量而不是文字值,这些语句可能会运行得更快。
- 识别执行全表扫描的语句
- 识别执行多个磁盘读取或具有高 CPU 消耗的语句。
- 比较解析和执行的次数。理想的情况是解析是针对多次执行单次发生的
- 查看 CPU 和 I/O 统计信息,看看哪些语句消耗的系统资源最多
- 单个 SQL 的行数也有助于找出低效之处。检查表是否以错误的顺序连接
八、跟踪文件分析器 (TRCA)
与 TKPROF 一样,跟踪分析器 (TRCA) 工具可以帮助你分析事件 10046 生成的一个或多个 SQL 跟踪,以生成可用于诊断性能不佳的 SQ 语句的输出诊断报告。TRCA 可以产生两种格式的输出(html 和文本)。
TRCA 识别昂贵的 SQL,生成它们的解释计划并收集一些其他有用的信息,例如基于成本的优化器 CBO 统计信息、元数据、配置参数和影响查询性能的类似元素。
1、使用 TRCA 的步骤
与数据库捆绑的 TKPROF 不同,你需要单独安装 TRCA。以下是安装它和生成报告的基本步骤。
1、下载软件
TRCANLZR (TRCA): SQL_TRACE/Event 10046 Trace File Analyzer - Tool for Interpreting Raw SQL Traces (Doc ID 224270.1)
2、安装软件
注意:为了获得最佳输出结果,必须在生成跟踪的同一系统和数据库中安装和使用 TRCA。请注意,TRCA 能够使用不同的系统分析轨迹。
unzip trca.zip
cd ./trca/install
sqlplus / as sysdba
@tacreate.sql
- 用户 TRCANLZR 的密码(在 11g 中区分大小写)
- TRCANLZR 使用的表空间(你可以选择除 SYSTEM 之外的任何表空间)
- TRCA 用户(“TRCA 的主要应用程序用户是生成 SQL Trace 的模式所有者进行分析。例如,在 EBS 应用程序上,你将输入 APPS。系统不会要求你输入其密码。要在安装完成后添加更多 TRCA 用户,只需授予他们 TRCA_USER_ROLE 角色即可。”)
- Flag to create将表暂存为永久或临时对象(建议使用临时“T”和默认值。)
3、生成 TRCA 报告
cd trca/run
sqlplus [apps user]/[apps pwd]
start trcanlzr.sql ora_123_xyz.trc
4、卸载
- 以 SYSDBA 身份连接
- 执行 trca/install/tadrop.sql
九、优化器模式
Oracle 的基于成本的优化器 OPTIMIZER_MODE 建立了选择优化方法的默认行为。选择正确的模式设置可以将查询的平均性能提高很多倍。优化器是 Oracle 引擎的核心,它考虑了许多因素,如索引、统计信息等,并决定获取数据并返回到用户会话的最佳路径。Oracle 提供了一些参数,如果对这些参数进行调整,可以使优化器模式切换到对你的 SQL 查询有益的替代方式。optimizer_mode 数据库参数就是这样一个有用的参数。
1、OPTIMIZER_MODE 的可能值
下面提到了我们通常用于这些参数的关键值。还有其他值,如“规则”和“选择”,但现在很少或从未使用过这些值,因此我们不会在这里讨论这些值。
first_rows
优化器找到快速交付前几行的最佳计划。这里的目标是尽快获取数据,即使整个查询运行时间更长。这种方法通常使用索引而不是全扫描,因为索引访问会更快。因此,对于 OLTP 类系统,这种模式可能会在用户只想快速查看小结果的情况下多次证明是有用的。
first_rows_n
优化器使用基于成本的方法并以最佳响应时间为目标进行优化以返回前 n 行(其中 n = 1、10、100、1000)。所以这就像使用 firs_rows 方法,但另外告诉 CBO 带来确切的行数。告知有关行数的附加信息可能有助于 CBO 进一步制定正确的访问路径以获取数据。
all_rows
优化器对会话中的所有 SQL 语句使用基于成本的方法,并以最佳吞吐量为目标进行优化。目标是尽量减少整个语句的资源使用,而不是快速提供部分结果。此方法可能有利于并行全表扫描而不是索引扫描。因此,这种模式可以证明对实时查看不是目标但快速获取整个数据是目标的数据仓库类应用程序很有帮助
请注意,这是 Oracle 数据库使用的默认模式。
2、如何验证你使用的是什么优化器模式
简单的 show parameter 命令会告诉你当前的优化器模式是什么。
SQL> show parameter optimizer_mode
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
optimizer_mode string ALL_ROWS
3、在特定SQL级别覆盖默认优化器模式
对于单个 SQL 语句,我们可以使用提示来覆盖默认的优化器模式。
使用ALL_ROWS 提示 以最佳吞吐量(最小总资源消耗)为目标优化语句块
SELECT /*+ ALL_ROWS */ EMP_NO, ENAME,....
使用FIRST_ROWS 提示以最佳响应时间为目标优化语句块以返回前几行。
SELECT /*+ FIRST_ROWS */ EMP_NO, ENAME, ....
当你只需要获取特定数量的记录 (1,10,100,1000) 时,使用FIRST_ROWS(n) 提示。
SELECT /*+ FIRST_ROWS (10) */ EMP_NO, ENAME,...
4、在会话/系统级别更改优化器模式
对于会话级别更改:
ALTER SESSION SET OPTIMIZER_MODE = FIRST_ROWS;
对于系统级别更改:
ALTER SYSTEM SET OPTIMIZER_MODE = FIRST_ROWS SCOPE=SPFILE;
5、仅为特定用户更改优化器模式
如果你希望特定用户始终使用特定的优化器模式,那么你可以为其创建触发器:
create or replace trigger set_optimizer_mode
after logon
on database
begin
if user like 'XXPO' then
execute immediate 'alter session set optimizer_mode=all_rows';
end if;
end;
/
请注意,统计信息对于优化器模式的正常工作非常重要。数据库对象统计信息不能过时以获得最佳执行计划。
十、直方图
直方图有助于 Oracle 优化器生成更好的执行计划,特别是当表中的数据高度倾斜时。可以说直方图是一种可选的特殊类型的列统计数据,它提供了有关表列中实际数据分布的更详细信息。
1、用简单的非技术术语表示的直方图
直方图是数值数据分布的准确表示。它是一种条形图。要构建直方图,请将整个值范围划分为一系列区间,然后计算每个区间内有多少值。间隔必须相邻,并且通常大小相等。在“间隔”上竖立了一个矩形,其高度与频率成正比——每个间隔中的案例数。
直方图是研究数据分布最常用的统计工具之一。统计学家使用直方图可视化数据集的形状,并确定数据集中是否存在间隙或簇。直方图给出数据底层分布密度的粗略感觉,此信息可用于 SQL 查询
2、ORACLE如何使用直方图
直方图告诉优化器列中数据的分布情况。如果没有直方图,优化器会假定行在列中的不同值之间均匀分布。
假设有一个名为 ENGINE 的表有 10,000 条记录,并且它的列名称为 SALE_COUNTRY。此列存储有关每个国家/地区销售的发动机数量的信息。假设发动机仅销往三个国家:印度、美国和英国。
假设 9000 台发动机销往印度,900 台销往美国,100 台销往英国。
表:ENGINE
列名称:SALE_COUNTRY
你运行了一个 SQL 查询来找出有多少引擎卖给了英国。
没有直方图
优化器将通过将表中的总行数除以列中不同值的数量来计算基数(返回的行数)。
基数= Total_records/number_of_distinct _values= 10000/3= 3333
由于 SALE_COUNTRY 列中的数据分布不均匀,因此基数估计显示为 3333,而对于英国,我们只有 100 条记录。考虑到如此高的基数,Oracle 可能会尝试在此处使用全扫描,查询成本会很高。
直方图的存在改变了优化器用来估计基数的公式,并允许它生成更准确的执行计划。因此,在上述情况下,Oracle 大多会查看直方图并选择低成本的索引范围扫描(如果可用)。
3、直方图的类型
Oracle使用两种直方图主要用于列统计:高度平衡直方图和频率直方图。
-
高度-平衡直方图:当不同值多于桶数时,使用基于高度的直方图。在这种类型中,列值被划分为多个波段,以便每个波段包含大致相同数量的行。在此直方图中,值将均匀分布在桶中。
-
Frequency Histograms : 这种类型的直方图更精确,被Oracle使用得更广泛。该列的每个值对应于直方图的一个桶。这也称为基于值的直方图。每个桶仅包含该单个值的出现次数。当不同值的数量小于或等于指定的直方图桶数时,将自动创建频率直方图。
Oracle 12c 还引入了混合直方图,它结合了基于高度的直方图和频率直方图的特点,还引入了Top-frequency直方图 ,它是频率直方图的变体,其中直方图只关注流行的值,忽略不受欢迎的值。
4、如何验证你的表是否使用直方图
你可以查询 DBA_TAB_COL_STATISTICS 或 USER_TAB_COL_STATISTICS 视图以轻松获取此信息。
5、与直方图相关的关键数据库参数
METHOD_OPT
这是告诉 Oracle 引擎在收集统计信息时创建直方图的参数。
从 10g 开始,METHOD_OPT 的默认值是“FOR ALL COLUMNS SIZE AUTO ”。
以下是 METHOD 的可能值
- AUTO:Oracle根据数据分布和列的工作量来决定采集直方图的列。
- REPEAT:仅在已有直方图的列上收集直方图。
- SKEWONLY : Oracle根据列的数据分布情况来决定收集直方图的列。
- INTEGER VALUE:直方图桶的数量。1 -254 之间的任何值。请注意,设置 1 将禁用直方图收集
这基本上意味着 Oracle 将自动在那些数据分布偏斜的列上创建直方图,并且有 SQL 语句引用这些列。验证你当前的设置
SQL> select dbms_stats.get_prefs ('METHOD_OPT') from dual;
DBMS_STATS.GET_PREFS('METHOD_OPT')
--------------------------------------------------------------------------------
FOR ALL COLUMNS SIZE AUTO
TO CHANGE YOUR SETTING TO “REPEAT”
SQL> exec dbms_stats.set_global_prefs ('METHOD_OPT','FOR ALL COLUMNS SIZE REPEAT');
TO DISABLE THE HISTOGRAM COLLECTION
SQL> exec dbms_stats.set_global_prefs ('METHOD_OPT','FOR ALL COLUMNS SIZE 1');
6、如何创建/删除直方图
如果 DBMS_STATS 收集统计信息用于表,并且查询引用了该表中的列,则 Oracle 数据库会根据需要自动创建直方图。Oracle 引擎根据数据库中运行的用户查询定期更新数据字典表 SYS.COL_USAGE$。
你可以简单地让 Oracle 收集它想要的所有直方图,然后删除任何导致性能问题的直方图,然后设置首选项以告诉优化器不要再次收集它。
以下命令删除 EMP_ID 列上的直方图:
begin
dbms_stats.Delete_column_stats(ownname => 'SCOTT', tabname => 'EMP', colname => 'EMP_ID', col_stat_type => 'HISTOGRAM');
end;
/
以下命令阻止优化器在 EMP 表的 EMP_ID 列上进一步创建直方图:
BEGIN
dbms_stats.Set_table_prefs('SCOTT', 'EMP', 'METHOD_OPT'=>'FOR ALL COLUMNS SIZE AUTO, FOR COLUMNS SIZE 1 EMP_ID');
end;
/
7、何时创建直方图
在以下情况下创建直方图:
-
- 为包含在 WHERE 子句中的列创建
-
- 以及当列高度倾斜时。
请注意,直方图不仅适用于索引列,还适用于非索引列
不要在以下情况下创建直方图:
- 1)列中的数据是均匀分布的。
-
- 列不在where 子句中使用。
-
- 不要在表的每一列上创建,因为这会增加统计信息收集时间、解析时间,并且还会导致优化生成错误的计划。
- 4)不要在主键上创建直方图。
-
- 当列是唯一的且仅与等式谓词一起使用时,不要创建直方图
8、直方图提示
- 频率直方图比高度平衡直方图更精确。
- 直方图存储在字典中,维护和空间成本就在那里。因此,仅在需要时创建直方图。
- col_usage$ 表中没有谓词信息的列不会收集直方图。
- col_usage$ 仅在谓词和硬解析中引用的列发生时才会填充。
十一、分析性能问题的步骤
计划周密的方法是性能调优成功的关键。如果没有正确诊断问题,则采取的任何故障排除步骤都会进一步延迟解决。例如,当仔细分析的所有症状都指向磁盘/内存/网络等问题时,DBA 不能盲目地开始跟踪/调整 SQL/会话。
还要记住,最常见的性能提升是通过 SQL/代码/应用程序调整获得的,增加硬件资源应该永远是你最后的选择。开发人员在使用有效的 SQL 语句编写应用程序方面发挥着重要作用,因此在面对数据库/应用程序问题时,DBA 和开发人员应该一起工作很重要。
当 DBA 收到性能问题报告时,第一步是尽可能多地获取与该问题相关的信息。你可以向用户/开发人员询问以下示例初步问题,以收集第一级信息。
- 执行什么操作/程序?
- 是 Oracle 种子还是自定义程序?
- 以前用了多少时间?
- 运行时间是否随着时间的推移而增加,或者你看到运行时间突然增加?
- 最近有没有代码更改/迁移?
- 是总是很慢还是只在一天中的特定时间?
- 是所有参数都慢还是某些特定参数慢?
- 处理了多少数据?
- 作业执行的频率是多少?频率有变化吗?
- 问题是否同时发生在他们的测试和生产系统上?
提出上述问题将帮助你决定应该针对系统的哪一部分。
- 瞄准整个系统
- 针对单个会话
- 以单个 SQL 语句为目标
你的目标应该是回答以下三个问题:
- 时间花在哪里?
你需要确定时间消耗在哪里。是代码或网络延迟还是磁盘 I/O 瓶颈或 CPU/内存紧缩
- 时间是怎么度过的?
你需要找出时间是如何花费的以及在每一层花费了多少时间——数据库、应用程序、网络、磁盘等。
- 如何减少花费的时间?
最后,根据以上信息了解大部分时间花在了哪些地方以及如何减少它。
系统级性能问题的高级步骤
- 使用 vmstat top/prstat 确定系统范围内的 CPU/内存消耗。
- 使用 iostat 验证磁盘是否是瓶颈
- 使用 netstat/tnsping 等来验证网络是否有问题。
- 验证服务器上是否正在运行任何其他资源密集型进程。
- 验证文件系统空间。
- 检查警报日志、应用程序日志、跟踪等。
- 检查数据库锁
- 生成 AWR 报告以查看是什么在消耗资源。
- 检查增加应用程序/数据库内存/重做/撤消/临时/SGA 是否有帮助。
SQL 级性能问题的高级步骤
- 应用跟踪、生成 TKPROF 文件并分析最消耗资源的 SQL。
- 避免对大表进行全表扫描
- WHERE 子句中包含的列的可能索引
- 使用 AWR/ASH 报告获取集合信息
- 还使用 SQLTRPT/SQLT
- 验证统计数据是最新的
- 验证索引是否有效且足够。
- 验证并行性/物化视图/基线/SQL 配置文件是否有帮助
- 监视 V$SESSION_LONGOPS 以检测长时间运行的操作
- 如果有帮助,请决定使用提示。
- 可以将表分区视为基于表的种类和大小的选项。
十二、动态性能视图
你可以利用 Oracle 数据库动态性能视图来查询与调优相关的重要参数,例如内存利用率、磁盘 I/O、磁盘结构等。这些动态性能视图是在数据库打开和使用时不断更新的特殊视图。
请注意,实际的动态性能视图由前缀 V_$ 标识。这些视图的公共同义词具有前缀 V$。你应该只访问 V$ 对象,而不是 V_$ 对象。
V$ 与 GV$ 观看次数
=> 对于 RAC 数据库,几乎每个 V$ 视图都有一个相应的 GV$(全局 V$)视图。
=> 在 RAC 数据库中,查询 GV$ 视图会从所有符合条件的实例中检索 V$ 视图信息。
=> 每个 GV$ 视图都包含一个名为 INST_ID 的数据类型为 NUMBER 的额外列。
=> GV$ 视图中的 INST_ID 列具有从中获取相关 V$ 视图信息的实例编号。
1、关键动态性能视图
1、V$OSSTAT
- 当你无权访问数据库服务器但想查看操作系统级别参数值时有用的视图
- 表中“COMMENTS”栏对参数进行说明。
- “Cumulative”列为“YES”的列具有自数据库实例启动以来的累积值。
- “CUMULATIVE”列为“NO”的列,表示该值为常数/当前值。
2、V$EVENT_NAME
- Oracle 有很多等待事件((1200+),这些等待事件分为 13 个等待类。
- 你可能需要找出哪个等待事件属于哪个等待类。例如,如果你收到“pipe get”,甚至你可能需要查看这是否是“IDLE”等待事件。
3、V$SESSION
V$SESSION 有很多列,这里不可能描述所有列。我们仅提及我们经常引用的几个列名称。有关其他信息,请参阅 Oracle 数据库参考手册
- V$SESSION 是一个关键的动态视图,你将经常使用它。
- V$SESSION 存储当前数据库会话以及会话正在做什么
- STATUS 列会告诉你会话是否处于活动/非活动/终止状态等
- TYPE 列将告诉你会话是用于 BACKGROUND 进程还是 USER 进程。
- LOGON_TIME 会告诉你会话何时初始化。
- USERNAME 会告诉你哪个数据库用户与数据库建立了连接
- SCHEMANAME 将告诉你会话连接到哪个数据库模式
- OSUSER 会告诉你哪个操作系统用户执行了它
- SQL_ID 列将告诉你当前会话执行的 SQL
- LAST_CALL_ET 将告诉你会话处于当前状态的时间
- PREV_SQL_D 将告诉你在当前 SQL_ID 之前执行的 SQL 的 SQL_ID
- STATE 列将显示当前是否正在等待语句。
4、V$PROCESS
该视图包含有关当前活动进程的信息。
- SPID——操作系统进程标识符
- USERNAME – 操作系统进程用户名。
- BACKGROUND – 1 用于后台进程;正常进程为 NULL
- PGA_USED_MEM – 进程当前使用的 PGA 内存
- PGA_MAX_MEM – 进程曾经分配的最大 PGA 内存
5、V$SQL 和 V$SQLAREA
- 有关与 SQL 语句关联的游标的信息在父级可用,存储在 V$SQLAREA 中
- 有关与 SQL 语句关联的游标的信息在子级别可用,存储在 V$SQL 中。
- 可以搜索 SQL_ID 列来查找 SQL 信息
- SQL_TEXT 列提供前 1,000 个字符
- SQL_FULLTEXT 提供完整的 SQL 语句文本。
- PROGRAM_ID – 如果执行了 Pl/SQL,则显示 pl/sql 程序的 ID
- PROGRAM_LINE# – 如果执行了 Pl/SQL,那么 SQL 所在的行号。
- LOADS – 硬解析发生的次数
- FIRST_LOAD_TIME – 第一次发生硬解析
- LAST_LOAD_TIME – 上次发生硬解析的时间
- SQL_PROFILE - 生成执行计划时使用的 SQL 配置文件的名称。
- SQL_PLAN_BASELINE – 生成执行计划期间使用的 SQL 基线的名称
- PLAN_HASH_VALUE – 链接到 SQL 的执行计划的哈希值
- ROWS_PROCESSED - SQL 处理了多少行
- ELAPSED_TIME- 用于处理的数据库时间量
十三、自动工作负载存储库 (AWR) 基础知识
Automatic Workload Repository (AWR) 会自动保留所有级别(会话级别除外)的大多数统计信息的累积值和增量值。
这个过程在固定的时间段内重复,结果称为 AWR 快照。快照捕获的增量值表示每个统计数据在一段时间内的变化。
自动工作负载存储库 (AWR) 收集、处理和维护性能统计数据,以用于问题检测和自我调整目的。这些数据既在内存中,又存储在数据库中。
STATISTICS_LEVEL参数的概念:
默认情况下启用使用 AWR 收集数据库统计信息,并由 STATISTICS_LEVEL 初始化参数控制。STATISTICS_LEVEL 参数应设置为 TYPICAL 或 ALL 以启用 AWR 收集统计信息。默认设置为典型。将 STATISTICS_LEVEL 设置为 BASIC 会禁用许多 Oracle 数据库功能,包括 AWR,因此不推荐这样做。
SQL>show parameter STATISTICS_LEVEL
1、快照的概念
快照是特定时间段的历史数据集,用于 ADDM 的性能比较。
默认情况下,Oracle 数据库每小时自动生成一次性能数据快照,并将统计信息在负载存储库中保留 8 天。
2、管理快照
OEM 是易于使用的快照管理工具,但如果你不使用 OEM,请使用以下手动方式。
A) 创建快照:
你可以使用 CREATE_SNAPSHOT 过程手动创建快照,以便在与自动生成的快照不同的时间捕获统计信息。例如:
begin
DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT ();
end;
/
B) 删除快照
你可以使用 DROP_SNAPSHOT_RANGE 过程删除一系列快照。要查看快照 ID 的列表以及数据库 ID,请检查 DBA_HIST_SNAPSHOT 视图。例如,你可以删除以下范围的快照:
begin
DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE (low_snap_id => 22, high_snap_id => 32, dbid => 3310949047);
end;
/
当调用 DROP_SNAPSHOT_RANGE 过程时,属于快照范围指定时间段的活动会话历史数据 (ASH) 也会被清除。
C) 修改快照设置
你可以为指定的数据库 ID 调整快照生成的间隔、保留和捕获的 Top SQL,但请注意,这会影响 Oracle 数据库诊断工具的精度。
INTERVAL 设置影响数据库自动生成快照的频率。RETENTION 设置会影响数据库在工作负载存储库中存储快照的时间。TOPNSQL 设置会影响每个 SQL 条件(已用时间、CPU 时间、解析调用、可共享内存和版本计数)要刷新的 Top SQL 的数量。此设置的值不受统计/刷新级别的影响,并将覆盖 AWR SQL 集合的系统默认行为。可以将此设置的值设置为 MAXIMUM 以捕获共享 SQL 区域中的完整 SQL 集,尽管这样做(或将值设置为非常高的数字)可能会导致可能的空间和性能问题,因为将有更多数据需要收集和存储。要调整设置,请使用 MODIFY_SNAPSHOT_SETTINGS 过程。例如:
BEGIN
DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS( retention => 43200, interval => 30, topnsql => 100, dbid => 3310949047);
END;
/
2、基线的概念
基线包含来自特定时间段的性能数据,这些数据会保留下来,以便在出现性能问题时与其他类似的工作负载时间段进行比较。基线中包含的快照从自动 AWR 清除过程中排除并无限期保留。
Oracle 数据库中有多种类型的可用基线:
- 固定基线
固定的基线对应于过去固定的、连续的时间段
- 移动窗口基线
移动窗口基线对应于 AWR 保留期内存在的所有 AWR 数据。Oracle 数据库自动维护系统定义的移动窗口基线。系统定义的移动窗口基线的默认窗口大小是当前 AWR 保留期,默认情况下为 8 天
- 基线模板
你还可以使用基线模板为未来的连续时间段创建基线。有两种类型的基线模板:单一模板和重复模板。
你可以使用单个基线模板为将来的单个连续时间段创建基线。
你可以使用重复基线模板根据重复时间表创建和删除基线。如果你希望 Oracle 数据库持续自动捕获连续的时间段,这将非常有用。
3、管理基线
A)创建基线
1.查看 DBA_HIST_SNAPSHOT 视图中的现有快照以确定要使用的快照范围。
2.使用 CREATE_BASELINE 过程使用所需的快照范围创建基线:
BEGIN
DBMS_WORKLOAD_REPOSITORY.CREATE_BASELINE (start_snap_id => 270,
end_snap_id => 280, baseline_name => 'peak baseline',
dbid => 3310949047, expiration => 30);
END;
/
B) 放弃基线
你可能希望定期删除不再用于节省磁盘空间的基线。与基线关联的快照将无限期保留,直到你明确删除基线或基线已过期。
要删除基线:
1.查看 DBA_HIST_BASELINE 视图中的现有基线以确定要删除的基线。
2.使用 DROP_BASELINE 过程删除所需的基线:
BEGIN
DBMS_WORKLOAD_REPOSITORY.DROP_BASELINE (baseline_name => 'peak baseline',
cascade => FALSE, dbid => 3310949047);
END;
/
在示例中,baseline 的名称为 peak baseline。cascade 参数设置为 FALSE,指定仅删除基线。将此参数设置为 TRUE 指定删除操作还将删除与基线关联的快照。可选的 dbid 参数指定数据库。标识符,在此示例中为 3310949047。如果你没有为 dbid 指定值,则本地数据库标识符将用作默认值。
C) 重命名基线
要重命名基线:
1.查看 DBA_HIST_BASELINE 视图中的现有基线以确定要重命名的基线。
2.使用 RENAME_BASELINE 过程重命名所需的基线:
BEGIN
DBMS_WORKLOAD_REPOSITORY.RENAME_BASELINE (
old_baseline_name => 'peak baseline',
new_baseline_name => 'peak mondays',
dbid => 3310949047);
END;
/
在此示例中,基线的名称从 old_baseline_name 参数指定的峰值基线重命名为 new_baseline_name 参数指定的峰值星期一。
生成自动工作负载存储库报告
1) 生成 AWR 报告
在 SQL 提示符下,输入:
@$ORACLE_HOME/rdbms/admin/awrrpt.sql
Enter value for report_type: text or HTML
Enter value for num_days: 2
Enter value for begin_snap: 150
Enter value for end_snap: 160
Enter value for report_name:
Using the report name awrrpt_1_150_160
2) 生成 Oracle RAC AWR 报告
awrgrpt.sql SQL 脚本生成一个 HTML 或文本报告,该报告使用当前数据库标识符和 Oracle Real Application Clusters (Oracle RAC) 环境中的所有可用数据库实例显示一系列快照 ID 的统计信息。
在 SQL 提示符下,输入:
@$ORACLE_HOME/rdbms/admin/awrgrpt.sql
Enter value for report_type: text or HTML
Enter value for num_days: 2
Enter value for begin_snap: 150
Enter value for end_snap: 160
Enter value for report_name:
Using the report name awrrpt_rac_150_160.html
3) 生成特定数据库实例的 AWR 报告
awrrpti.sql SQL 脚本生成一个 HTML 或文本报告,显示使用特定数据库和实例的一系列快照 ID 的统计信息。此脚本使你能够指定将为其生成 AWR 报告的数据库标识符和实例。
@$ORACLE_HOME/rdbms/admin/awrrpti.sql
Enter value for report_type: text
A list of available database identifiers and instance numbers are displayed:
Instances in this Workload Repository schema
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DB Id Inst Num DB Name Instance Host
----------- -------- ------------ ------------ ------------
3309173529 1 MAIN main examp1690
3309173529 1 TINT251 tint251 samp251
Enter value for dbid: 3309173529
Enter value for inst_num: 1
Enter value for num_days: 2
Enter value for num_days: 2
Enter value for begin_snap: 150
Enter value for end_snap: 160
Enter value for report_name:
Using the report name awrrpt_1_150_160
使用报告名称 awrrpt_1_150_160
4) 生成特定数据库实例的 Oracle RAC AWR 报告
awrgrpti.sql SQL 脚本生成一个 HTML 或文本报告,显示使用在 Oracle RAC 环境中运行的特定数据库和实例的一系列快照 ID 的统计信息。
@$ORACLE_HOME/rdbms/admin/awrgrpti.sql
为 report_type 输入值:html
输入 dbid 的值:3309173529
输入 instance_numbers_or_all 的值:1,2
输入 num_days 的值:2
为 begin_snap 输入值:150
输入 end_snap 的值:160
输入 report_name 的值:
使用报告名称 awrrpt_rac_150_160.html
5) 为 SQL 语句生成 AWR 报告
awrsqrpt.sql SQL 脚本生成一个 HTML 或文本报告,显示特定 SQL 语句对一系列快照 ID 的统计信息。运行此报告以检查或调试 SQL 语句的性能。
@$ORACLE_HOME/rdbms/admin/awrgrpti.sql
Enter value for report_type: html
Enter value for dbid: 3309173529
Enter value for instance_numbers_or_all: 1,2
Enter value for num_days: 2
Enter value for begin_snap: 150
Enter value for end_snap: 160
Enter value for report_name:
Using the report name awrrpt_rac_150_160.html
6) 为特定数据库实例上的 SQL 语句生成 AWR 报告
awrsqrpi.sql SQL 脚本生成一个 HTML 或文本报告,显示使用特定数据库和实例的一系列快照 ID 的特定 SQL 语句的统计信息。
@$ORACLE_HOME/rdbms/admin/awrsqrpi.sql
Enter value for report_type: html
Enter value for dbid: 3309173529
Using 3309173529 for database Id
Enter value for inst_num: 1
Using 1 for instance number
Enter value for num_days: 1
Enter value for begin_snap: 146
Enter value for end_snap: 147
Enter value for sql_id: 2b064ybzkwf1y
Enter value for report_name:
Using the report name awrrpt_1_146_147.html
生成自动工作负载存储库比较期间报告
AWR 报告显示两个快照(或两个时间点)之间的 AWR 数据,而 AWR 比较期间报告显示两个期间(或两个 AWR 报告,相当于四个快照)之间的差异。使用 AWR Compare Periods 报告可帮助你识别两个时间段之间不同的详细性能属性和配置设置。
例如,如果已知应用程序工作负载在每晚 10:00 到午夜之间稳定,但特定星期四的性能在晚上 10:00 到 11:00 之间很差,则生成星期四的 AWR 比较周期报告从晚上 10:00 到晚上 11:00 和星期三晚上 10:00 到晚上 11:00 应该确定在这些时间段内不同的配置设置、工作负载配置文件和统计数据。根据差异,你可以更轻松地诊断性能下降的原因。为 AWR Compare Periods Report 选择的两个时间段可以有不同的持续时间,因为该报告根据每个时间段在数据库上花费的时间量对统计数据进行归一化,并显示按期间之间最大差异排序的统计数据。
1) 生成 AWR 比较期间报告
@$ORACLE_HOME/rdbms/admin/awrddrpt.sql
Enter value for report_type: html
Enter value for num_days: 2
Specify a beginning and ending snapshot ID for the first time period:
Enter value for begin_snap: 102
Enter value for end_snap: 103
Specify the number of days for which you want to list snapshot IDs in the second time period.
Enter value for num_days2: 1
Specify a beginning and ending snapshot ID for the second time period:
Enter value for begin_snap2: 126
Enter value for end_snap2: 127
Enter a report name, or accept the default report name:
Enter value for report_name:
Using the report name awrdiff_1_102_1_126.txt
2) 生成 Oracle RAC AWR 比较期间报告
@$ORACLE_HOME/rdbms/admin/awrgdrpt.sql
Enter value for report_type: html
Enter value for num_days: 2
Specify a beginning and ending snapshot ID for the first time period:
Enter value for begin_snap: 102
Enter value for end_snap: 103
Specify the number of days for which you want to list snapshot IDs in the second time period.
Enter value for num_days2: 1
Specify a beginning and ending snapshot ID for the second time period:
Enter value for begin_snap2: 126
Enter value for end_snap2: 127
Enter a report name, or accept the default report name:
Enter value for report_name:
Using the report name awrracdiff_1st_1_2nd_1.html
3) 生成特定数据库实例的 AWR 比较周期报告
@$ORACLE_HOME/rdbms/admin/awrddrpi.sql
Enter value for report_type: text
Instances in this Workload Repository schema
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DB Id Inst Num DB Name Instance Host
----------- -------- ------------ ------------ ------------
3309173529 1 ORA ORA1 examp1690
3309173529 1 ORA2 ORA251 samp251
Enter value for dbid: 3309173529
Using 3309173529 for Database Id for the first pair of snapshots
Enter value for inst_num: 1
Using 1 for Instance Number for the first pair of snapshots
Enter value for num_days: 2
Enter value for begin_snap: 102
Enter value for end_snap: 103
Enter value for dbid2: 3309173529
Using 3309173529 for Database Id for the second pair of snapshots
Enter value for inst_num2: 1
Using 1 for Instance Number for the second pair of snapshots
Enter value for num_days2: 1
Enter value for begin_snap2: 126
Enter value for end_snap2: 127
Enter value for report_name:
Using the report name awrdiff_1_102_1_126.txt
4) 生成特定数据库实例的 Oracle RAC AWR 比较周期报告
awrgdrpi.sql SQL 脚本生成一个 HTML 或文本报告,该报告使用 Oracle RAC 环境中的特定数据库和实例比较两个选定时间段之间的详细性能属性和配置设置。
@$ORACLE_HOME/rdbms/admin/awrgdrpi.sql
Enter value for report_type: html
Instances in this Workload Repository schema
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DB Id Inst Num DB Name Instance Host
----------- -------- ------------ ------------ ------------
3309173529 1 MAIN main examp1690
3309173529 1 ORA251 ORA251 samp251
Enter value for dbid: 3309173529
Using 3309173529 for Database Id for the first pair of snapshots
Enter value for inst_num: 1,2
Using instances 1 for the first pair of snapshots
Enter value for num_days: 2
Enter value for begin_snap: 102
Enter value for end_snap: 103
Instances in this Workload Repository schema
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DB Id Inst Num DB Name Instance Host
----------- -------- ------------ ------------ ------------
3309173529 1 MAIN main examp1690
3309173529 1 ORA251 ORA251 samp251
3309173529 2 ORA251 ORA252 samp252
Enter value for dbid2: 3309173529
Using 3309173529 for Database Id for the second pair of snapshots
Enter value for instance_numbers_or_all2: 3,4
Enter value for num_days2: 1
Specify a beginning and ending snapshot ID for the second time period:
Enter value for begin_snap2: 126
Enter value for end_snap2: 127
Enter value for report_name:
Using the report name awrracdiff_1st_1_2nd_1.html
十四、活动会话历史记录 (ASH) 基础知识
活动会话历史记录 (ASH) 采样器执行采样。ASH 对所有活动会话的当前状态进行采样。数据库将此数据收集到内存中,你可以在内存中使用 V$ 视图访问它。
使用 ASH 使你能够检查 V$ACTIVE_SESSION_HISTORY 视图中的当前数据和 DBA_HIST_ACTIVE_SESS_HISTORY 视图中的历史数据并对其执行详细分析,通常无需重放工作负载来收集额外的性能跟踪信息。
ASH 还包含每个捕获的 SQL 语句的执行计划信息。你可以使用此信息来确定 SQL 执行的哪一部分对 SQL 运行时间的贡献最大。ASH 中存在的数据可以在它捕获的各种维度上汇总,包括以下内容:
-
SQL 语句的SQL 标识符
-
SQL 计划标识符和用于执行SQL 语句的SQL 计划的哈希值
-
SQL 执行计划信息
-
对象编号、文件编号和块编号
-
等待事件标识符和参数
-
会话标识符和会话序列号
-
模块和动作名称
-
会话的客户端标识符
-
服务散列标识符
-
消费者组标识符
你可以将指定持续时间内的 ASH 信息收集到报告中。
1、生成 ASH 报告
OEM 是一种无需任何额外麻烦即可生成 ASH 报告的好工具。下面我们记录了手动生成 ASH 的方式。ashrpt.sql SQL 脚本生成一个 HTML 或文本报告,在指定的持续时间内显示 ASH 信息。
当它提示你输入开始时间时,你可以给出一个实际日期,以及精确到分钟和秒的时间,或者如果你想从 20 分钟前的开始时间开始,只需键入 -20(是的,负 20)。对于持续时间,请给出你希望报告涵盖的分钟数,你可以选择事件发生前的几分钟和事件发生后的几分钟。通常不要尝试超过 10-15 分钟的持续时间。
@$ORACLE_HOME/rdbms/admin/ashrpt.sql
Enter value for report_type: text
Specify the begin time in minutes before the system date:
Enter value for begin_time: -10
Enter the duration in minutes that the report for which you want to capture ASH information from the begin time.
Enter value for duration:
Enter a report name, or accept the default report name:
Enter value for report_name:
Using the report name ashrpt_1_0310_0131.txt
生成特定数据库实例的 ASH 报告
ashrpti.sql SQL 脚本生成一个 HTML 或文本报告,显示指定数据库和实例在指定持续时间内的 ASH 信息。
2、生成 Oracle RAC ASH 报告
ashrpti.sql SQL 脚本生成一个 HTML 或文本报告,显示 Oracle RAC 环境中指定数据库和实例在指定持续时间内的 ASH 信息。
生成报告后,查找以下内容:
-
平均活动会话: 此统计信息越多,你的数据库就越忙。所以通常如果你看到几十个或几百个,那你就有问题了!
-
热门用户事件: 这让你了解在你运行报告的时间跨度内等待最多的事件是什么。% Event 让你了解特定等待事件对整体等待的贡献程度。
-
Top SQL Command Types: 这会让你了解运行最多的操作,通常 UPDATE/DELETES 等可能会显示锁等。所以要注意。
-
Top SQL with TOP Events: 这是主要部分,向你显示相关时间段内最昂贵的 SQL 以及它们的 SQL ID 和导致延迟的数据库等待事件。
还有其他细节,但是上面的这4个可以让你快速了解是什么让数据库变慢了,而且这些ASH报告比AWR报告要简洁得多,更重要的是,ASH更加精细。
确定 SQL ID 后,你可以更深入地研究计划,并可能针对有问题的 SQL 制定解决方案。
十五、AWR 报告分析
https://expertoracle.com/2018/02/06/performance-tuning-basics-15-awr-report-analysis/
十六、使用 SQL 调优健康检查脚本 (SQLHC)
与 SQLT 不同,此工具 SQLHC 不需要在数据库中安装任何代码来提供推荐。SQLHC 使用已经执行过并在内存中的语句的 SQL_ID 来生成报告,因此它实际上不会再次执行 SQL all lover。SQLHC 适用于 10g 及更高版本。SQLHC 也支持 RAC
1、SQLHC可以提供哪些信息:
该工具可以为你提供的一些关键信息如下:
- 解释 SQL ID 的计划和任何更改
- 各种统计数据和参数的有效性以及简要说明
- 表和索引详细信息
- 对象统计详细信息
- SQL_TEXT 和 SQL 配置文件,基线详细信息
- 历史计划详情
- 来自动态性能视图的许多其他信息片段。
好处是它可以让你免于运行多个脚本和收集上述所有数据。运行单个 SQLHC 会累积所有数据并以 HTML 易于阅读的格式呈现。
2、在哪里下载这个脚本:
你可以从以下 Oracle MOS Note ID 下载代码:
SQL 调优健康检查脚本 (SQLHC)(文档 ID 1366133.1)
3、如何运行此健康检查脚本:
从 MOS 下载 scrip 代码并上传到你的服务器后,接下来要做的就是找到你要对其进行性能评估的 SQL_ID。你可以从 AWR 或 ASH 报告中找到语句的 SQL_ID,或者你可以使用 V$SQL 视图从数据库中选择它。当针对一个 SQL_ID 执行时,此脚本会生成一个 HTML 报告,其中包含围绕提供的一个 SQL 语句进行的一组健康检查的结果。
转到你上传 SQLHC 脚本代码的位置。从以 SYS、DBA 或有权访问数据字典视图的用户连接的 SQL*Plus 执行此脚本所需参数
它需要两个参数:
a) Oracle 包许可(调优、诊断或无)[T|D|N](必需)
注意:如果站点同时具有调优和诊断许可,则指定 T(Oracle 调优包包括 Oracle 诊断)
b) 要分析的 SQL 的有效 SQL_ID。
$ unzip sqlhc.zip
Archive: sqlhc.zip
creating: sqlhc/
inflating: sqlhc/sqlhc.sql
inflating: sqlhc/sqldx.sql
inflating: sqlhc/sqlhcxec.sql
$ cd sqlhc
$ ls -tlr
total 2
-rw-r--r-- 1 mfggprd dba 48747 Nov 11 2013 sqldx.sql
-rw-r--r-- 1 mfggprd dba 288298 Apr 16 2014 sqlhc.sql
-rw-r--r-- 1 mfggprd dba 292838 Apr 16 2014 sqlhcxec.sql
$ sqlplus / as sysdba
SQL> @sqlhc.sql T 1w6s3ayu0kw8m
如果安装了 Diagnostic 或 Tuning pack,SQLHC 可以使用来自 AWR 报告的信息,它会询问这些包是否在你的站点获得许可。
如果他们获得许可,则对该问题回答“是”以执行其他检查。如果他们没有获得许可,则回答“否”。
在我们的例子中,因为我们拥有所有的调整/诊断包,所以我们只是在执行时直接提到“T”。
它将在你执行的同一目录中生成一个 ZIP 文件。你将该文件复制到本地计算机以供分析。
十七、引用链接
https://expertoracle.com/2017/11/15/db-tuning-basics-1-selectivity-and-cardinality/
https://expertoracle.com/2017/11/16/db-tuning-basics-2-parsing/
https://expertoracle.com/2017/11/17/db-tuning-basics-3-parent-and-child-cursors/
https://expertoracle.com/2017/11/18/db-tuning-basics-4-bind-variables/
https://expertoracle.com/2017/11/24/db-tuning-basics-5-trace-and-tkprof/
https://expertoracle.com/2017/11/24/db-tuning-basics-6-trace-and-tkprof-part-2-generating-tkprof/
https://expertoracle.com/2017/11/24/performance-tuning-basics-7-trace-and-tkprof-part-3-analyzing-tkprof-files/
https://expertoracle.com/2017/11/24/db-tuning-basics-8-trace-file-analyzer/
https://expertoracle.com/2017/11/25/db-tuning-basics-6-optimizier-mode/
https://expertoracle.com/2017/11/28/db-tuning-basics-8-histograms/
https://expertoracle.com/2017/12/07/performance-tuning-basics-11-steps-to-analyze-a-performance-problem/
https://expertoracle.com/2018/01/08/performance-tuning-basics-12-dynamic-performance-views/
https://expertoracle.com/2018/01/23/automatic-workload-repository-awr-basics/
https://expertoracle.com/2018/01/23/active-sessions-history-ash-basics/
https://expertoracle.com/2018/02/06/performance-tuning-basics-15-awr-report-analysis/
https://expertoracle.com/2018/04/01/performance-tuning-basics-16-using-sql-tuning-health-check-script-sqlhc/