Sql 在查询上或查询中使用NVL的优点

Sql 在查询上或查询中使用NVL的优点,sql,oracle,Sql,Oracle,假设我有下表: create table xxnvloror ( XX_ID NUMBER , ITEM VARCHAR2(100) , AMOUNT NUMBER ); 我在其中插入了10000条记录,在金额中加入了一些空值: Declare l_amount number; BEGIN for i in 1..10000 loop if mod(i, 2) = 0 then

假设我有下表:

create table xxnvloror
(   XX_ID       NUMBER
,   ITEM        VARCHAR2(100)
,   AMOUNT      NUMBER
);
我在其中插入了10000条记录,在金额中加入了一些空值:

Declare 

    l_amount number;

BEGIN

    for i in 1..10000 loop

        if mod(i, 2) = 0 then

            l_amount := null;

        else

            l_amount := i;

        end if;

        insert into xxnvloror
        (   XX_ID  
        ,   ITEM   
        ,   AMOUNT 
        )
        VALUES
        (
            i
        ,   'item-'||i
        ,   l_amount
        );  

    end loop;

END;
我使用了以下两个查询:

select  *
from    xxnvloror
where   amount is null or amount = 0;

select  *
from    xxnvloror
where   nvl(amount, 0) = 0;
我查看了他们的解释计划,他们似乎并不重要:

Plan hash value: 1982466860

-------------------------------------------------------------------------------
| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           |  5000 | 80000 | 15087   (1)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| XXNVLOROR |  5000 | 80000 | 15087   (1)| 00:00:01 |
-------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("AMOUNT" IS NULL OR "AMOUNT"=0)

Plan hash value: 1982466860

-------------------------------------------------------------------------------
| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           |  5001 | 80016 | 15088   (1)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| XXNVLOROR |  5001 | 80016 | 15088   (1)| 00:00:01 |
-------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(NVL("AMOUNT",0)=0)

如果没有任何索引,使用NVL是否比OR有任何优势,反之亦然?

在索引的范围内,资源使用、I/O或性能不会有任何差异

如果没有任何索引,引擎将执行完整的表扫描。它将从堆中读取所有行,并计算谓词值以决定是保留还是放弃每一行。两个谓词之间的CPU使用率差异很小


此外,谓词的选择性不够。它选择了大约50%的表格。在这种情况下,全表扫描是最佳选择。

在索引的asbence中,资源使用、I/O或性能不会有任何差异

如果没有任何索引,引擎将执行完整的表扫描。它将从堆中读取所有行,并计算谓词值以决定是保留还是放弃每一行。两个谓词之间的CPU使用率差异很小


此外,谓词的选择性不够。它选择了大约50%的表格。在这种情况下,全表扫描是最佳选择。

实际上,这样的查询:

where amount is null or amount = 0
可以使用金额索引。因此,该公式通常更可取


我应该补充一点,Oracle支持基于函数的索引。因此,如果你有一个关于nvlamount,0的索引,那么其中nvlamount,0=0会更好。

实际上,这样的查询:

where amount is null or amount = 0
可以使用金额索引。因此,该公式通常更可取

我应该补充一点,Oracle支持基于函数的索引。所以,如果你有一个关于nvlamount,0的索引,那么nvlamount,0=0会更好