I've just tried this in PostgreSQL for comparison on a table with 1000 rows and three columns (id, a TEXT, b TEXT) and indices on a and b. ``` wolfgang=> explain select * from t1 where (a = 'a500' or 'a500' is null); QUERY PLAN ---------------------------------------------------------------- Index Scan using t1_a on t1 (cost=0.28..8.29 rows=1 width=12) Index Cond: (a = 'a500'::text) (2 Zeilen) wolfgang=> explain select * from t1 where (a = 'a500' or 'a500' is null) and (b = null or null is null); QUERY PLAN ---------------------------------------------------------------- Index Scan using t1_a on t1 (cost=0.28..8.29 rows=1 width=12) Index Cond: (a = 'a500'::text) (2 Zeilen) wolfgang=> explain select * from t1 where (a = 'a500' or 'a500' is null) and (b = 'b500' or 'b500' is null); QUERY PLAN ---------------------------------------------------------------- Index Scan using t1_b on t1 (cost=0.28..8.29 rows=1 width=12) Index Cond: (b = 'b500'::text) Filter: (a = 'a500'::text) (3 Zeilen) ``` So here the behavior is as I expect, assuming that "Index Scan" means an index lookup - one index is used, and the other condition is either ignored (if the parameter is NULL) or applied as a filter. It seems to work exactly the same with parameters, like this: ``` PREPARE foo1 (text) AS SELECT * FROM t1 WHERE ($1 IS NULL OR a=$1); EXPLAIN EXECUTE foo1('a500'); ```