与NULL或使用NVL函数相比,哪个更好?

时间:2018-11-28 12:00:05

标签: sql oracle

如果输入为NULL或输入为非NULL的特定记录,哪种方法更好地获取所有条目的输出? 这是针对Oracle数据库上的PL / SQL。让我知道我的第一种方法是否错误

select * from student where (roll_no = :ROLL_NO or :ROLL_NO is NULL);

OR

select * from student where roll_no = NVL(:ROLL_NO, roll_no);

4 个答案:

答案 0 :(得分:5)

roll_no为空的情况下,这两种方法将给出不同的结果,因为对于这些行,roll_no = roll_no将不成立。

如果有索引,则优化器具有somecol = nvl(:param,somecol)的特殊情况,您将在执行计划中看到两个FILTER操作和一个CONCATENATION,表示{ {1}}为空或不为空。因此,只要将:param定义为nvl列,我就使用roll_no表达式。

答案 1 :(得分:1)

通常,使用运算符是一种更好的方法。这是因为当列不是函数的参数时,优化器可以更聪明。

此答案假定roll_no不是null

尽管有时可能会遇到Oracle优化器的情况,但是您可能会发现,当存在适当的索引时,使用union all编写查询实际上会产生更好的执行计划:

select s.*
from student s
where roll_no = :ROLL_NO
union all
select s.*
from student s
where :ROLL_NO is NULL;

答案 2 :(得分:0)

第二种方法只需稍作修改即可得到相同的结果(无法将null与null进行比较):

select * from student where NVL(roll_no,1) = NVL(NVL(:ROLL_NO, roll_no),1);

答案 3 :(得分:0)

威廉·罗伯逊(William Robertson)提出了一个好观点。那我明白我的错误。 我尝试了Gordon Linoff的答案。有效。 我认为waldemort的答案也将是正确的,但我没有尝试过。

下面的答案是我对此的解决方案,它可能与waldemort的答案类似。

{{select * from student where AND (roll_no = nvl(roll_no,1) = nvl(:roll_no,1)}

感谢帮助人员