暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 19C 在TKPROF解释中避免陷阱的准则

原创 Asher.HU 2021-02-04
380


解释TKPROF输出时,有助于了解常见陷阱。

本节包含以下主题:

 

22.5.4.1避免参数陷阱的指南

如果您不知道在运行时绑定的值,则有可能陷入参数陷阱。

EXPLAIN PLAN无法根据SQL语句的文本确定绑定变量的类型,并且始终假定类型为VARCHAR如果绑定变量实际上是数字或日期,则TKPROF可能导致隐式数据转换,这可能导致执行效率低下的计划。为避免这种情况,请在查询中尝试使用不同的数据类型,然后自己执行转换。

 

22.5.4.2避免读取一致性陷阱的指南

在不知道未提交的事务对列进行了一系列更新的情况下,很难理解为什么会发生如此多的块访问。

这种情况通常是不可重复的。如果再次运行该流程,则另一个事务不太可能以相同的方式与其交互。

SELECT name_id
FROM cq_names 
WHERE name = 'FLOOR';

call     count     cpu     elapsed     disk     query current     rows
----     -----     ---     -------     ----     ----- -------     ----
Parse        1    0.10        0.18        0         0       0        0
Execute      1    0.00        0.00        0         0       0        0
Fetch        1    0.11        0.21        2       101       0        1

Misses in library cache during parse: 1
Parsing user id: 01 (USER1)

Rows     Execution Plan
e----     --------- ----
   0     SELECT STATEMENT
   1       TABLE ACCESS (BY ROWID) OF 'CQ_NAMES'
   2         INDEX (RANGE SCAN) OF 'CQ_NAMES_NAME' (NON_UNIQUE) 
复制

 

22.5.4.3避免架构陷阱的准则

在某些情况下,一个看似直接的索引查询将查看许多数据库块并以当前模式访问它们。

以下示例显示了模式陷阱的一个极端示例(因此很容易检测到):

SELECT name_id
FROM cq_names 
WHERE name = 'FLOOR';

call        count        cpu      elapsed     disk  query current rows
--------  -------   --------    ---------  ------- ------ ------- ----
Parse           1       0.06         0.10        0      0       0    0
Execute         1       0.02         0.02        0      0       0    0 
Fetch           1       0.23         0.30       31     31       3    1

Misses in library cache during parse: 0
Parsing user id: 02  (USER2)

Rows     Execution Plan
-------  ---------------------------------------------------
      0  SELECT STATEMENT
   2340    TABLE ACCESS (BY ROWID) OF 'CQ_NAMES'
      0      INDEX (RANGE SCAN) OF 'CQ_NAMES_NAME' (NON-UNIQUE)
复制

有两个统计数据表明该查询可能是通过全表扫描执行的:当前模式块访问,以及计划中来自“表访问”行源的行数。原因是所需的索引是在生成跟踪文件之后但在TKPROF运行之前生成的生成新的跟踪文件将提供以下数据:

SELECT name_id
FROM cq_names 
WHERE name = 'FLOOR'; 

call    count    cpu   elapsed  disk  query current     rows
-----  ------ ------  -------- ----- ------ -------    -----
Parse       1   0.01      0.02     0      0       0        0
Execute     1   0.00      0.00     0      0       0        0
Fetch       1   0.00      0.00     0      2       0        1

Misses in library cache during parse: 0
Parsing user id: 02  (USER2)

Rows     Execution Plan
-------  ---------------------------------------------------
      0  SELECT STATEMENT
      1    TABLE ACCESS (BY ROWID) OF 'CQ_NAMES'
      2      INDEX (RANGE SCAN) OF 'CQ_NAMES_NAME' (NON-UNIQUE)
复制

在正确的版本中,解析调用花费了10毫秒的CPU时间和20毫秒的经过时间,但是查询显然没有时间执行和执行提取。这些异常的出现是因为10毫秒的时钟滴答声相对于执行和获取数据所花费的时间太长。在这种情况下,重要的是要使语句多次执行,这样您就可以得到统计上有效的数字。

 

22.5.4.4避免时间陷阱的准则

在某些情况下,查询会花费很长时间。

例如,以下对7行的更新将在19秒内执行:

UPDATE cq_names 
  SET ATTRIBUTES = lower(ATTRIBUTES)
  WHERE ATTRIBUTES = :att 

call       count       cpu    elapsed     disk    query current        rows
-------- -------  --------  --------- -------- -------- -------  ----------
Parse          1      0.06       0.24        0        0       0           0
Execute        1      0.62      19.62       22      526      12           7
Fetch          0      0.00       0.00        0        0       0           0

Misses in library cache during parse: 1
Parsing user id: 02  (USER2)

Rows     Execution Plan
-------  ---------------------------------------------------
      0  UPDATE STATEMENT
   2519  TABLE ACCESS (FULL) OF 'CQ_NAMES'
复制

解释是来自另一笔交易的干扰。在这种情况下,另一个事务在cq_names发布更新之前和之后都在表上持有共享锁几秒钟。诊断经验是否正在发生需要经验。一方面,当干扰仅造成短时延迟(或在先前示例中,块访问量略有增加)时,比较数据至关重要。但是,如果干扰仅造成适度的开销,并且如果该语句实质上是有效的,则可能不需要分析其统计信息。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论