Oracle PL/SQL NVL/LENGTH/TRIM 调用速度与 IS NOT NULL AND != ' '

Oracle PL/SQL speed of NVL/LENGTH/TRIM calls versus IS NOT NULL AND != ' '

我试图找到检查 CHAR/VARCHAR2 变量是否包含字符的最佳方法(NULL 或空格应视为相同,如 "no-value"):

我知道有几种解决方案,但 (NVL(LENGTH(TRIM(v)),0) > 0) 似乎比 (v IS NOT NULL AND v != ' ')

知道为什么吗?还是我的测试代码做错了什么?

在 Linux、UTF-8 db charset ...

上使用 Oracle 18c 进行了测试

我得到以下结果:

时间:+000000000 00:00:03.582731000

时间:+000000000 00:00:02.494980000

set serveroutput on;

create or replace procedure test1
is
    ts timestamp(3);
    x integer;
    y integer;
    v char(500);
    --v varchar2(500);
    begin
    ts := systimestamp;
    --v := null;
    v := 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
    for x in 1..50000000
    loop
        if v is not null and v != ' ' then
           y := x;
        end if;
    end loop;
    dbms_output.put_line('time:' || (systimestamp - ts) ) ;
    end;
/

create or replace procedure test2
is
    ts timestamp(3);
    x integer;
    y integer;
    v char(500);
    --v varchar2(500);
    begin
    ts := systimestamp;
    --v := null;
    v := 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
    for x in 1..50000000
    loop
        if nvl(length(trim(v)),0) > 0 then
           y := x;
        end if;
    end loop;
    dbms_output.put_line('time:' || (systimestamp - ts) ) ;
    end;
/

begin
    test1();
    test2();
end;
/

drop procedure test1;
drop procedure test2;

quit;

最佳做法是忽略小函数之间的速度差异,使用最简单的函数。

在现实的数据库编程中,运行 函数(如 NVLIS NOT NULL 的时间与从磁盘读取数据所需的时间或连接所需的时间相比完全无关紧要数据。如果一个函数每 5000 万行节省 1 秒,没有人会注意到。而如果 SQL 语句通过完整 table 扫描而不是使用索引读取 5000 万行,反之亦然,这可能会完全破坏应用程序。

很少有人关心数据库中的这类问题。 (但并非不可能 - 如果您有特定的用例,请将其添加到问题中。)如果您确实需要最佳程序代码,您可能需要考虑在 Java 或 C 中编写外部程序。