【问题标题】:dynamic sampled query in oracle db traceoracle db trace 中的动态采样查询
【发布时间】:2016-10-03 15:09:04
【问题描述】:

我有一个巨大的 Oracle 跟踪文件。生成此文件的应用程序运行了 1 小时 15 分钟。 在这个 Tracefile 中,我发现了 4 个 Selects 以及一个多小时的运行时间。 问题是这些选择是由优化器采样的。

SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE 
  NO_PARALLEL(SAMPLESUB) opt_param('parallel_execution_enabled', 'false') 
  NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE */ NVL(SUM(C1),:"SYS_B_00"), 
  NVL(SUM(C2),:"SYS_B_01") 
FROM
 (SELECT /*+ IGNORE_WHERE_CLAUSE NO_PARALLEL("LST_G") FULL("LST_G") 
  NO_PARALLEL_INDEX("LST_G") */ :"SYS_B_02" AS C1, CASE WHEN 
  "LST_G"."SENDUNG_TIX"=:"SYS_B_03" AND "LST_G"."LST_K"=:"SYS_B_04" AND 
  "LST_G"."LST_ART"=:"SYS_B_05" AND "LST_G"."FAK_TIX"=(-:"SYS_B_06") THEN 
  :"SYS_B_07" ELSE :"SYS_B_08" END AS C2 FROM "TMS1033"."LST_G" SAMPLE BLOCK 
  (:"SYS_B_09" , :"SYS_B_10") SEED (:"SYS_B_11") "LST_G") SAMPLESUB


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse    56076      3.93       4.21          0          0          0           0
Execute  56076      1.98       1.80          0          0          0           0
Fetch    56076   1127.54    1122.77        222   46487004          0       56076
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total   168228   1133.45    1128.79        222   46487004          0       56076

这是四个之一,它们看起来几乎相同。我想我找到了原始语句,这些语句是从 Uniface 服务执行的。我不知道 Uniface 是如何工作的,我只是 db 的人。 问题是我不知道优化器为什么要重建这个语句。原来的不使用dynamic_sample 提示。我还发现了这些,我想是的,原始状态还在跟踪文件中。

select count(*) 
from
 lst_g where sendung_tix = 10330805990396 and lst_k = 'E' and lst_art = 'G' 
  and fak_tix = -4

这就是为什么我不确定这些抽样语句是什么。有什么想法吗?

非常感谢。

【问题讨论】:

    标签: oracle oracle11g trace cost-based-optimizer


    【解决方案1】:

    已为该查询启用动态采样。要么

    1. 查询使用/*+ DYNAMIC_SAMPLING */ 提示
    2. 代码发出alter session set optimizer_dynamic_sampling= 命令
    3. optimizer_dynamic_sampling 在数据库 spfile 中设置。

    例如

    alter session set OPTIMIZER_DYNAMIC_SAMPLING = 2; 
    

    然后针对具有非常选择性(但不精确)条件的大表发出查询,该条件可以使用索引。

    select * from mtl_system_items /* biiig table */ 
    where organization_id = 92 
    and segment1 LIKE 'DY_'  /* very selective condition with index */
    

    运行它,您可以快速获取数据。但是,

    alter session set OPTIMIZER_DYNAMIC_SAMPLING = 10; 
    

    然后重新运行相同的SELECT,就可以吃午饭了,对表中的每个块进行采样。

    【讨论】:

    • 感谢您的解释
    【解决方案2】:

    我相信这些是统计收集作业用于更新数据库对象统计信息的查询。请检查在生成跟踪文件时是否有任何统计信息收集/更新作业正在运行。

    在您的情况下,从发布的 SQL 来看,似乎正在“TMS1033”.“LST_G”上收集统计信息。您发现的其他 3 个 SQL 也是如此。

    希望这会有所帮助。

    【讨论】:

    • 抱歉,我讨厌投反对票,但这是不对的。这些查询不是来自 DBMS_STATS。它们来自执行动态采样的优化器。您可以通过 (A) 查询中的 OPT_DYN_SAMP 注释和 (B) 查询在表中的特定列上具有 WHERE 子句这一事实来判断。 DBMS_STATS 将从所有行中采样(没有 where 子句,只是一个样本大小)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-09
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多