После создания аналогичной таблицы, ее заполнения, обновления статистики и, наконец, просмотра выходных данных EXPLAIN ANALYZE
, я вижу только одно отличие: первый запрос фильтруется следующим образом:
Filter: ((id = COALESCE(id)) AND (value = 3))
и второй фильтр, как это:
Filter: (value = 3)
Я вижу существенно разные планы производительности и выполнения, когда в столбце "значение" есть индекс. В первом случае
Bitmap Heap Scan on my_table (cost=19.52..552.60 rows=5 width=16) (actual time=19.311..20.679 rows=1000 loops=1)
Recheck Cond: (value = 3)
Filter: (id = COALESCE(id))
-> Bitmap Index Scan on t2 (cost=0.00..19.52 rows=968 width=0) (actual time=19.260..19.260 rows=1000 loops=1)
Index Cond: (value = 3)
Total runtime: 22.138 ms
а во втором
Bitmap Heap Scan on my_table (cost=19.76..550.42 rows=968 width=16) (actual time=0.302..1.293 rows=1000 loops=1)
Recheck Cond: (value = 3)
-> Bitmap Index Scan on t2 (cost=0.00..19.52 rows=968 width=0) (actual time=0.276..0.276 rows=1000 loops=1)
Index Cond: (value = 3)
Total runtime: 2.174 ms
Так что я бы сказал, что это медленнее, потому что движок БД а) оценивает выражение COALESCE (), а не оптимизирует его, и б) оценка его включает в себя дополнительное условие фильтра.