Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mysql, ifnull vs coalesce, which is faster?

if it's known that there are only two values to candidate for the result of a column,

ifnull(a, b) as a_or_b_1

and

coalesce(a, b) as a_or_b_2

will give the same result. but which is faster? when searching i found this article, which says ifnull is faster. but it was the only article i found. any views on this?

thanks in advance :)

like image 599
davogotland Avatar asked Jan 20 '11 13:01

davogotland


People also ask

Which one is faster coalesce or Isnull?

Mladen aka spirit1 posted a speed test of COALESCE vs. ISNULL. Reported result: COALESCE is faster.

Which is faster coalesce or case?

COALESCE() is literally shorthand for a CASE statement, they will perform identically. However, as podiluska mentioned, ISNULL() can be occasionally faster than a CASE statement, but it's likely to be a miniscule increase as these functions are very unlikely to bottleneck your procedure.

Does coalesce improve performance?

In the case of coalesce, each input partition is included in exactly one output partition. This causes massive performance improvements in the case of coalesce, when you're decreasing the number of partitions. If you're increasing the number of partitions, a coalesce is identical to a repartition.

What is the difference between Ifnull () and coalesce ()?

ifnull can only replace a null value of the first parameter. Whereas coalesce can replace any value with another value. With coalesce in standard SQL you can have many parameters transforming many values.


2 Answers

My view is that you should benchmark for your usage.

I doubt there will be much difference. Bear in mind that while a single benchmark might suggest that one is slightly better, variation in the data over time might change that result.

Also note that COALESCE has been part of standard SQL since 1992 - I'm not sure IFNULL is in any standard yet.

There's a nice article by Adam Machanic about benchmarking an equivalent scenario - Performance: ISNULL vs. COALESCE (in SQL Server). Note some of the provisos on getting a valid test.

like image 118
martin clayton Avatar answered Nov 02 '22 04:11

martin clayton


Since an answer was never given for MySQL, here's a custom procedure that shows IFNULL is about 10% slower than COALESCE for larger datasets.

CREATE PROCEDURE `compare_ifnull_coalesce`(max_var INT)
BEGIN
    DECLARE COALESCE_BOTH_NOT_NULL INT(11);
    DECLARE IFNULL_BOTH_NOT_NULL INT(11);
    DECLARE COALESCE_FIRST_NULL INT(11);
    DECLARE IFNULL_FIRST_NULL INT(11);
    DECLARE i INT DEFAULT 1;
    DECLARE StartDate DATETIME DEFAULT SYSDATE(3);
    WHILE i <= max_var DO
        IF (SELECT COALESCE('a', 'b') = 'b') THEN
            SELECT 1;
        END IF;
        SET i = i + 1;
    END WHILE;
    SET COALESCE_BOTH_NOT_NULL = FLOOR(TIMESTAMPDIFF(MICROSECOND, StartDate, SYSDATE(3))/1000);
    SET i = 1;
    SET StartDate = SYSDATE(3);
    WHILE i <= max_var DO
        IF (SELECT IFNULL('a', 'b') = 'b') THEN
            SELECT 1;
        END IF;
        SET i = i + 1;
    END WHILE;
    SET IFNULL_BOTH_NOT_NULL = FLOOR(TIMESTAMPDIFF(MICROSECOND, StartDate, SYSDATE(3))/1000);
    SET i = 1;
    SET StartDate = SYSDATE(3);
    WHILE i <= max_var DO
        IF (SELECT COALESCE(null, 'b') = 'a') THEN
            SELECT 1;
        END IF;
        SET i = i + 1;
    END WHILE;
    SET COALESCE_FIRST_NULL = FLOOR(TIMESTAMPDIFF(MICROSECOND, StartDate, SYSDATE(3))/1000);
    SET i = 1;
    SET StartDate = SYSDATE(3);
    WHILE i <= max_var DO
        IF (SELECT COALESCE(null, 'b') = 'a') THEN
            SELECT 1;
        END IF;
        SET i = i + 1;
    END WHILE;
    SET IFNULL_FIRST_NULL = FLOOR(TIMESTAMPDIFF(MICROSECOND, StartDate, SYSDATE(3))/1000);
    SELECT
        'both columns not null' AS `SCENARIO`,
        CONCAT('Total milliseconds: ', COALESCE_BOTH_NOT_NULL) AS `COALESCE`,
        CONCAT('Total milliseconds: ', IFNULL_BOTH_NOT_NULL) AS `IFNULL`
    UNION
    SELECT
        'first column null' AS `SCENARIO`,
        CONCAT('Total milliseconds: ', COALESCE_FIRST_NULL) AS `COALESCE`,
        CONCAT('Total milliseconds: ', IFNULL_FIRST_NULL) AS `IFNULL`
    ;
END;

Then, to get the results, just run:

CALL compare_ifnull_coalesce(1000000);
SCENARIO COALESCE IFNULL
both columns not null Total milliseconds: 5175 Total milliseconds: 5687
first column null Total milliseconds: 5185 Total milliseconds: 5793
like image 42
placidwolverine Avatar answered Nov 02 '22 05:11

placidwolverine