如何查找前 10 个最昂贵的 SQL -Oracle

S S*_*S S 5 database oracle oracle11g

我尝试过下面的 SQL 查询。

SELECT
    sql_id,
    child_number,
    sql_fulltext,
    elapsed_time,
    executions,
    round(elapsed_time_avg) elapsed_time_avg
FROM
    (
        SELECT
            command_type,
            sql_id,
            child_number,
            sql_fulltext,
            elapsed_time,
            cpu_time,
            disk_reads,
            executions,
            ( elapsed_time / executions ) elapsed_time_avg
        FROM
            v$sql
        WHERE
            executions > 0
        order by  elapsed_time_avg  desc 
    )
    where rownum <=10;
Run Code Online (Sandbox Code Playgroud)

我一直期望数据库中排名前 10 的昂贵查询。我的查询已获取,但一段时间后使用相同的 SQL 查询更改 SQL_id (结果更改)。

Jon*_*ler 2

你的做法是正确的。(哇,我建议按而不是平均值排序ELAPSED_TIME,因为最重要的是总运行时间。一百万个快速查询可能比一个慢速查询更糟糕。)但是您只需要记住,查询将会随着它们的出现而消失V$SQL。超出共享池的年龄。并且很难准确预测某些内容将在共享池中保留多长时间。

您可能想要查看 中的活动会话历史记录,其中V$ACTIVE_SESSION_HISTORY通常存储了数小时的数据。然后看一下DBA_HIST_ACTIVE_SESS_HISTORY,默认存储8天的数据。您必须调整查询,因为这两个视图不存储总和,它们为每次等待存储一行。您需要计算每个 SQL_ID 的行数才能找到估计的等待时间。(V$ACTIVE_SESSION_HISTORY每秒采样一次,DBA_HIST_ACTIVE_SESS_HISTORY每 10 秒采样一次。)

关于调优 SQL,要认识到的最重要的事情之一是您并不是在寻求完美。你不想追踪每一个语句,否则你会发疯的。如果您每隔 X 秒对系统进行一次采样,并且没有显示一条语句,那么您几乎肯定不关心该语句。如果慢语句从前 N 个列表中消失也没关系。