Home » SQL & PL/SQL » SQL & PL/SQL » NVL vs IS NULL (12c)
NVL vs IS NULL [message #642997] Thu, 24 September 2015 11:54 Go to next message
deepakdot
Messages: 89
Registered: July 2015
Member
Hi

Which one gives better performance , NVL or IS NULL ?

Option1: Select * from T1 where NVL(Col1, 10) > 9;

Option2: Select * from T1 where Col1 > 9 OR Col1 IS NULL;

Which one better to use. When i check the explain plan i did not see much difference.

Thanks
Deepak Samal
Re: NVL vs IS NULL [message #642999 is a reply to message #642997] Thu, 24 September 2015 12:17 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

If there is one it is small as the optimizer is aware of the meaning of NVL function.

Re: NVL vs IS NULL [message #643001 is a reply to message #642997] Thu, 24 September 2015 20:18 Go to previous messageGo to next message
EdStevens
Messages: 1376
Registered: September 2013
Senior Member
deepakdot wrote on Thu, 24 September 2015 11:54
Hi

Which one gives better performance , NVL or IS NULL ?

Option1: Select * from T1 where NVL(Col1, 10) > 9;

Option2: Select * from T1 where Col1 > 9 OR Col1 IS NULL;

Which one better to use. When i check the explain plan i did not see much difference.

Thanks
Deepak Samal



What does your own testing, in your own situation, reveal?
Re: NVL vs IS NULL [message #643002 is a reply to message #643001] Thu, 24 September 2015 23:49 Go to previous messageGo to next message
deepakdot
Messages: 89
Registered: July 2015
Member
In our application we have a last_date columns which hold the value after which the row is no more valid.. For e.g if the last_date column values is 15-NOV-2015, then that row is not more valid after this date.. If it is a NULL (No value mention) then there is no last date and It is valid for ever.

So in our query generally we are saying

Select * from Table1 Where VALUE(LAST_DATE, '31-DEC-9999') > :TodayDate

Which mean , give me the data where the LAST_DATE is NULL or Where the Value is greater than today.

If i change this to
Select * from Table1 Where (LAST_DATE > :TodayDate OR LAST_DATE is NULL )

Here Both are return same result. But i want to perfomracne / general practice which is better. While i see the explain plan for both the query in our database, i did not see any difference.

Re: NVL vs IS NULL [message #643003 is a reply to message #643002] Fri, 25 September 2015 00:42 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Michel Cadot wrote on Thu, 24 September 2015 19:17
If there is one it is small as the optimizer is aware of the meaning of NVL function.



EdStevens wrote on Fri, 25 September 2015 03:18
What does your own testing, in your own situation, reveal?


Re: NVL vs IS NULL [message #643009 is a reply to message #643002] Fri, 25 September 2015 05:44 Go to previous messageGo to next message
gazzag
Messages: 1118
Registered: November 2010
Location: Bedwas, UK
Senior Member
Quote:
While i see the explain plan for both the query in our database, i did not see any difference.

You have answered your own question Smile
Re: NVL vs IS NULL [message #643010 is a reply to message #643009] Fri, 25 September 2015 06:05 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
Of course in this case you could add a function based index for the nvl which may speed it up noticeably.
Re: NVL vs IS NULL [message #643013 is a reply to message #643002] Fri, 25 September 2015 06:38 Go to previous messageGo to next message
EdStevens
Messages: 1376
Registered: September 2013
Senior Member
deepakdot wrote on Thu, 24 September 2015 23:49

Here Both are return same result.


Then, as Gazzag said, you have answered your own question.



Quote:
But i want to perfomracne / general practice which is better. While i see the explain plan for both the query in our database, i did not see any difference.



For performance, you must keep in mind that nearly every performance related question must be considered 'in situ' (I leave it as an exercise for the student to research the term 'in situ')

For 'best practice', I'd keep in mind writing code that is easily understood and maintainable by someone other than the original author. (That attitude seems to be increasingly vanishing.) Which version of the code requires explanation, and which is plainly obvious in its intent? (You have also already answered that question.)

And when considering the potential trade-off between simple, easily understood code and performance, you need to keep in mind the business impact of the less performant code. Let's say you have an OLTP transaction and the 'obvious' code completes in 0.75 seconds, while the 'clever' code completes in 0.375 seconds. Or consider a batch job that runs at off-hours. The job with the 'obvious' code completes in 5 minutes while the job with the 'clever' code completes in 2.5 minutes. In either case, the 'clever' code produced a 50% reduction in time, but does anyone really care? Is the OLTP user going to be more productive with a transaction that completes 0.375 seconds faster? Are any users going to see an improvement in their use of the system because last nights batch job completed 2.5 minutes earlier?

Re: NVL vs IS NULL [message #643014 is a reply to message #643002] Fri, 25 September 2015 09:00 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
deepakdot wrote on Fri, 25 September 2015 00:49
In our application we have a last_date columns which hold the value after which the row is no more valid.. For e.g if the last_date column values is 15-NOV-2015, then that row is not more valid after this date.. If it is a NULL (No value mention) then there is no last date and It is valid for ever.


Bad design. I'd suggest using DATE '9999-12-31' instead of null. Then all you need is:

Select * from Table1 Where LAST_DATE > :TodayDate


Now it could use index (assuming LAST_DATE is indexed).

SY.
Re: NVL vs IS NULL [message #643015 is a reply to message #642997] Fri, 25 September 2015 09:39 Go to previous messageGo to next message
John Watson
Messages: 8931
Registered: January 2010
Location: Global Village
Senior Member
I just ran this procedure through dbms_profiler,
create or replace procedure p1 as
n number;
begin
for i in 1..100000 loop
select 1 into n from dual where nvl(dummy,'X') > 'A';
select 1 into n from dual where dummy > 'A' or dummy is null;
end loop;
end;
/

the line with NVL took 1955455297 nanoseconds, the line with the OR took 1944632052 nanoseconds. So, over a hundred thousand executions, the difference is about one hundredth of a second. Is that statistically significant?

I am of course prepared to believe that my test is not valid. There could be any number of optimizations when addressing the DUAL object.

I'll attach the script, in case anyone is interested.
Re: NVL vs IS NULL [message #643016 is a reply to message #643014] Fri, 25 September 2015 09:45 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Quote:
I'd suggest using DATE '9999-12-31' instead of null.


Jonathan Lewis has demonstrated, many years ago, that this is not the good practice.
The reason is that this will fool the optimizer about statistics (range of values) on the column, above all when you have no histograms on the column but also with it (until 12c where histograms have been enhanced).

See the chapter 6 "Selectivity issues", section "Deadly defaults" and chapter 7 "Histograms", section "Dangerous defaults" of his "Cost-Based Oracle Fundamentals" book.

Re: NVL vs IS NULL [message #643022 is a reply to message #643016] Fri, 25 September 2015 11:45 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
Yes, so what prevents OP from collecting stats with histograms? This is no different from having table with highly skewed data (it just we skew data by using not null default and might not realize that). And Jonathan never says it is not good practice. He just says - solution is histograms. This way selectivity is calculated correctly and index is used.

SY.
Re: NVL vs IS NULL [message #643025 is a reply to message #643022] Fri, 25 September 2015 12:28 Go to previous message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Quote:
This is no different from having table with highly skewed data


This is not true.
There you'll have quite compact data between say, 2000 and 2015, and nothing between 2015 and 9999 and a new pick for 31-12-9999.
Until 12c Oracle optimizer had not the histograms to handle this case and what he sees is about that there are many data each year between, say, 2000 and 2015 and very few between 2015 and 9999 (exactly the number in 9999 divided by (9999-2015), so if you ask for your pseudo-null value it will use the index as it thinks there are about 8000 times less rows than there actually are.

Quote:
And Jonathan never says it is not good practice. He just says - solution is histograms.


This is not correct, in the second section I mentioned he demonstrated why it is bad even with histograms (up to new 12c ones where new tests have to be made to see now the optimizer behaves).
As OP is in 12c he can take profit of new histograms but these ones have been created for other purpose than setting bad defaults.
If there is no value, the value is not known, or any value is meaningless for a specific row, then the "value" should be NULL.

Previous Topic: Procedure call through java
Next Topic: query rewrite
Goto Forum:
  


Current Time: Fri Apr 26 09:48:47 CDT 2024