【问题标题】:PLSQL oracle - what's more performant? NVL() or IS NULL?PLSQL oracle - 什么性能更好? NVL() 还是为空?
【发布时间】:2018-01-25 00:27:50
【问题描述】:

我需要迁移 400 万条记录。

在验证器中,检查一列是否为 NULL,什么更高效?

WHERE name IS NULL;

WHERE NVL(name,' ') = ' '

【问题讨论】:

  • 两者都是过滤谓词,但是第二个确实需要一个额外的函数来调用每一行。
  • 请注意,这些过滤谓词是不等价的 - 第二个将计算已经是单个空格 ' ' 的名称。
  • 另外,我们假设name 是一个VARCHAR2。

标签: sql oracle plsql database-migration


【解决方案1】:

在我的机器上为一个有 3689150 行的表:

create table t234 as
select editionable as name
from all_objects
cross join (
  select 1 from dual
  connect by level <= 50
);
select count(*) from t234;

  COUNT(*)
----------
   3689150

第一个更快:

set timing on
select count(*) from t234 where name is null;

  COUNT(*)
----------
   1612400

Elapsed: 00:00:00.094

select count(*) from t234 where NVL(name,' ') = ' ';

  COUNT(*)
----------
   1612400

Elapsed: 00:00:00.203

第一个查询需要 94 毫秒,第二个查询需要 203 毫秒,
所以第一个比 NOT NULL 操作符快 100% 以上 - 使用 NOT NULL 运算符而不是 NVL(name,' ') = ' ' 将节省超过 100 毫秒

【讨论】:

  • 这可能是真的;但它可能不是。像这样的单个挂钟比较远不足以支持您的结论。对于只需要大约 200 毫秒的东西,2 倍的性能差异并不是很引人注目(如果你看到 10 倍的改进,请打电话给我)。尝试以两个顺序(A 后 B,B 后 A)运行 10,000 次,然后查看性能差异是否真的显着。此外,您还没有指定许多因素,例如这运行在什么样的机器上,磁盘速度,缓冲区缓存的当前状态..
  • 此外,优化器根据列的num_nulls 统计数据知道有多少行为空,但它不知道有多少行与任意nvl() 表达式匹配。这可能会对涉及连接等的更复杂的查询产生影响。它可能会应用一个经验法则(例如'任何函数结果将匹配 5% 的行'),你可能幸运或不幸生成的连接顺序。
猜你喜欢
  • 2022-12-07
  • 2010-10-27
  • 1970-01-01
  • 2012-10-10
  • 2010-09-15
  • 1970-01-01
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多