Table of Contents

Oracle COALESCE vs NVL Performance

Share on facebook
Share on twitter
Share on linkedin
Share on email
Share on whatsapp
Share on pinterest
Share on print
oracle COALESCE vs NVL performance

Once comparing the Oracle COALESCE vs NVL performance most of the searches say those are mostly equal. But I also hope to do a complete analysis with data load for a simple example. Before moving into that let’s get to know about meaning and where to use oracle coalesce and NVL.

COALESCE  is the latest function and use ANSI-92 standard but NVL is Oracle defined in the late 80’s so it is very old. The main concern I have is these functions are implemented differently. Therefore evaluating performance is important.

NVL: evaluates both arguments

COALESCE: Looking for the arguments until find the NON-NULL value (exceptions, can be there such as sequence NEXTVAL):

Coalesce: The COALESCE function in Oracle looks for the first non-null value from the expression. Once the oracle reaches non null value stop the traverse through the remaining expressions. Therefore, it is a more versatile function because it handles multiple values and also its not evaluate all full expressions.

-- 
Syntax: 
COALESCE (expr1, expr2, ..., expr_n) 

SELECT COALESCE(NULL, 'A', 'B') AS result FROM dual; 
-- Output: 'A' 
--
  • expr1, expr2, …, expr_n: Evaluate the expression from 1 to n until find the non-null expression.

NVL: The NVL function evaluates both expressions and returns the default value if an expression is null. Otherwise, return the expression.

--Syntax:
NVL(expr, default) 

SELECT NVL(NULL, 'A') AS result FROM dual; 
-- Output: 'A' 
--
  • expr: Expression to be evaluated.
  • default: default value if an expression is null.

Performance Comparison:

Example 1: Simple Replacement

-- 
Using NVL: 
SELECT NVL(column_name, 'Default') FROM sample_table; 

-- 
Using COALESCE:
SELECT COALESCE(column_name, 'Default') FROM sample_table; 
--

For the small cases according to the above do the same thing. Therefore performance does not change in such a small situation.

Example 2: Handling Multiple Columns

-- Using NVL : 
--This is not support by oracle. you cant use more that 2 argument for NVL
SELECT NVL(column1, column2, 'Default') FROM sample_table; 
--
nvl error multi column
-- Using COALESCE 
SELECT COALESCE(column1, column2, 'Default') FROM sample_table; 
--

COALESCE is more versatile when for more than 2 columns in the arguments.

Example 3: Join Conditions

If you want to use NVL or COALESCE when join table that also possible. But my concern is there can be performance drop because of if there is a index on join columns those are may not fetch. Its because of we does not use columns as it is. Therefore we have to use function base index in those type of situations. Then oracle create index with function like COALESCE
-- Using NVL
SELECT * FROM table1 
JOIN table2 ON table1.column = NVL(table2.column, 'Default'); 

-- Using COALESCE 
SELECT * FROM table1 
JOIN table2 ON table1.column = COALESCE(table2.column, 'Default'); 
--

Both NVL and COALESCE can be used in the join table if you don’t have a complex function call as the default value performance is not changed.

Example 4: Handling Numeric Values

-- Using NVL 
SELECT NVL(numeric_column, 0) FROM sample_table; 
-- Using COALESCE 
SELECT COALESCE(numeric_column, 0) FROM sample_table; 
--

Both NVL and COALESCE can be used to set default values when the numeric column value returns null.

Above all the cases performance does not change. It’s because those are not complex let’s have some complex examples for performance comparison now I hope this will good example for the Oracle COALESCE vs NVL performance.

Oracle COALESCE vs NVL Performance Complete Analyze

Problem: I have a student table and fees column I would like to get the class fees from the fees column. So I have to check whether fees are available in the fees column otherwise, I have to calculate the amount in real-time and show it in the output result. I hope to add 10000 students to my table and add intentionally null for some students.

If the amount is null then I added a dummy calculation as a default calculation. This can be a function/procedure call for calculating student fees.

--
CREATE TABLE Students(
    student_id VARCHAR2(50) ,
    student_name VARCHAR2(100) ,    
    fees NUMBER,
    PRIMARY KEY(student_id)
);
-- Insert sample records
declare 
  -- insert 100000 records into database
   i integer:=0;
   fees_ integer:=null;
 
begin
    

LOOP
   i:= i+1;
   if (MOD(i,3))=  0 then 
      fees_:= null;
   else
      fees_:= round(dbms_random.value(1000,10000),0);
   end if;
   INSERT INTO Students (student_id, student_name, fees) 
   VALUES ('S-'||i,'Name-'||i,fees_);
   EXIT WHEN i > 9999;
END LOOP;
end;
--

here we have 2 queries one with NVL and the other one with COALESCE

connect by prior in Oracle performance issue
Connect by Prior in Oracle Performance Issue and How to Fix

NVL Example Code

-- NVL
SELECT  student_id, student_name,  (SELECT  SUM(val)
FROM    (
        SELECT  NVL(fees, LENGTH(RAWTOHEX(SYS_GUID()))) AS val
        FROM    dual
        CONNECT BY
                level <= 10000
        )) as fees
FROM  Students  
--

COALESCE Example Code

-- COALESCE
SELECT  student_id, student_name, (SELECT  SUM(val)
FROM    (
        SELECT  COALESCE(fees, LENGTH(RAWTOHEX(SYS_GUID()))) AS val
        FROM    dual
        CONNECT BY
                level <= 10000
        )) as fees
FROM  Students
--

NVL Code took a lot of time to fetch records from the database but the COALESCE query fetched records in considerably less time compared to NVL. It is because NVL and COALESCE have separate running mechanisms and my thinking is this kind of scenario COALESCE performs well.

oracle COALESCE vs NVL performance
Execution time for NVL- ITs took more time in this example
oracle COALESCE vs NVL performance
COALESCE took less time to take 10000 records- comparatively, it is fast in this case

I would like to add explanation plans for both cases you can see those EXPLAIN PLAN costs are equal but time not equal for both queries. It is because queues look equal but when running they have their mechanism to fetch data.

In this example, you can see Queries use FULL TABLE ACCESS to fetch data If you want you can have an Oracle index on the STUDENT table for required columns.

oracle COALESCE vs NVL performance
Cost is 13 and Cardinality is 13
oracle COALESCE vs NVL performance
Cost is 13 and Cardinality is 13

This is one good example of how to change Oracle COALESCE vs NVL performance. Therefore use NVL or Oracle COALESCE according to the situation. Because both are good if you use them in the correct place.

Now you can decide COALESCE to do everything that NVL can do. Is it? But in Some cases better to use NVL rather than COALESCE 

  • NVL – The huge benefit of NVL is no need to add both parameters in the same type.
  • COALESCE – Expect all the expressions in the same datatype therefore fore you have to add all the expressions in the same data type.
--
Select nvl('world', 123) result from dual;
--Result
--world

select coalesce(‘world’, 123) result from dual;

--Result
--Error: ORA-00932: inconsistent datatypes: expected CHAR got NUMBER
--

This is not related to Oracle COALESCE vs NVL performance but I thought to include this tip for your information.

Conclusion:

In conclusion, NVL is a much old function but there are a lot of benefits COALESCE doing the same thing and in addition, there are some extra benefits. If you doing some queries such as the above first 4 examples then considering performance there is not much difference with those. But if you have complex functions as a default value in NVL then that may be a concern in performance. COALESCE is good if you have a lot of possible columns as your expressions.

Reference

https://stackoverflow.com/questions/950084/oracle-differences-between-nvl-and-coalesce#:~:text=NVL%20and%20COALESCE%20are%20used,of%20a%20non%2DNull%20value.

Share on facebook
Share on twitter
Share on linkedin
Share on email
Share on whatsapp
Share on pinterest
Share on print

Leave a Comment

Your email address will not be published. Required fields are marked *

Related Posts

You May Like
Subscribe to our Newsletter
Related