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 |