1

假设有一个 C++ 应用程序在 Oracle 数据库上执行特定的 SQL 查询。

该查询在过去几年在客户环境中的生产环境中运行良好,但突然有一天,查询开始花费大约 10 倍的时间来执行。(假设在此查询工作的表中不断添加数据)。

在进行分析时,专家发现Oracle 的优化器没有生成最佳计划,原因可能与数据库统计/数据倾斜/所有其他可能影响优化器生成次优计划的参数有关。

通过在查询中放置提示来强制优化器生成一个好的执行计划非常有效。

应用程序开发团队现在被迫更改应用程序代码并在构建查询时将提示注入查询中。

应用程序开发团队不想更改应用程序代码,因为他们有数百名其他客户没有抱怨这种特定的查询性能。更改应用程序代码也意味着更多的维护成本,因为他们需要适当的机制来禁用提示,当客户将数据库升级到新版本时不再需要提示。

有问题的客户不愿意聘请可以执行 SQL 命令以使用计划基线功能调整查询的 DBA。

在这种情况下,应用程序开发团队有哪些选择?

4

1 回答 1

0

创建手动 SQL 配置文件以在不更改应用程序 SQL 的情况下注入提示。虽然这仍然是一项“DBA”任务,但它只需要运行一个命令,并且比 SQL 计划基线要简单得多

使用下面的 PL/SQL 块。替换 SQL_ID、名称、描述和提示列表,然后向客户发送完整的命令。

--Large SQL statements are better loaded from SQL_ID.
declare
    v_sql_id constant varchar2(128) := '2z0udr4rc402m';  --CHANGE ME
    v_sql    clob;
begin
    --Find the SQL, it should be in one of these.
    begin
        select sql_fulltext into v_sql from gv$sql where sql_id = v_sql_id and rownum = 1;
    exception when no_data_found then null;
    end;

    if v_sql is null then
        begin
            select sql_text into v_sql from dba_hist_sqltext where sql_id = v_sql_id and rownum = 1;
        exception when no_data_found then
            raise_application_error(-20000, 'Could not find this SQL_ID in GV$SQL or DBA_HIST_SQLTEXT.');
        end;
    end if;

    --Create profile.
    dbms_sqltune.import_sql_profile
    (
        sql_text    => v_sql,
        name        => 'Some_Meaningful_Name',  --CHANGE ME
        description => 'Add useful description here.',  --CHANGE ME
        force_match => true,
        profile     => sqlprof_attr('full(a)', 'parallel(8)')  --CHANGE ME
    );
end;
/

“最佳”解决方案是深入研究客户的系统,找出他们与其他人不同的原因。他们是否有一些奇怪的优化器参数,是否禁用了统计作业等。但如果这是客户唯一的问题,那么我只需使用 SQL 配置文件并将其称为完成。

于 2020-05-27T05:02:08.810 回答