【问题标题】:Why SQL statement is taking so long to execute PL/SQL when using variables?为什么 SQL 语句在使用变量时执行 PL/SQL 需要这么长时间?
【发布时间】:2018-04-13 20:14:03
【问题描述】:

我有一个包含 10 000 000 个随机数的表。该语句在大约 2 秒内执行(不创建索引)'select count(1) from myTableName where x + 200

declare
    cursor example is
        select count(1) countOf from padure where x + 200 < 500;
begin
    for i in example loop
        dbms_output.put_line(i.countOf);
    end loop;
end;

我在 0.2 秒内执行了所有块,但是,如果我这样做:

declare
    nbr constant integer := 200;
    cursor example is
        select count(1) countOf from padure where x + nbr < 500;
begin
    for i in example loop
        dbms_output.put_line(i.countOf);
    end loop;
end;

我在大约 2 秒内得到结果。 当我改用变量时,为什么它需要这么多时间才能执行此查询? 我怎样才能避免这种情况?或者如何实现与第一个示例相同的执行时间?

【问题讨论】:

    标签: oracle plsql database-indexes


    【解决方案1】:

    试试:

    nbr constant integer := 200;
    other_nbr constant integer := 500 - nbr;
    

    然后

    select count(1) countOf 
    from padure 
    where x < other_nbr;
    

    仅为x 创建一个索引,应该可以正常工作。

    问题是当您使用变量索引时不知道值为 200 并且必须评估每一行

    这样你只有一个常数,索引可以正常工作。

    一般规则,字段上的任何函数都会使索引不可用。

    【讨论】:

    • 如果我这样做,查询将不会使用我的索引。我的问题是,如果我不使用变量,为什么“相同”查询执行得更快?
    • 我解释一下。因为常数与变量不同。并且索引不知道变量是 200 与您的索引相同。
    • 其实它正在使用我的索引。如果我在代码execute immediate 'explain plan for select count(1) from padure where x + nbr &lt; 500' 中运行它,然后输出计划,它看起来像是一个索引范围扫描。
    • 然后向我们展示解释计划。为什么不试试我的解决方案?
    • 因为我知道它会起作用,但我没有这个索引。如果我将执行open cursorName for myQuery using nbr 之类的操作并定义一个动态变量而不是 nbr,它也会起作用,但我想知道为什么它不能以上面定义的方式工作。这里imgur.com/a/yDGuDexecute immediate 'explain plan for select count(1) from padure where x + ' || nbr || ' &lt; 500';的计划
    猜你喜欢
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多