Our database has a query that looks like this -- note the OR between a
simple equality qual and a LIKE qual:
=> explain SELECT 1 AS one FROM "redirect_routes" WHERE
redirect_routes.path = 'foobar' OR redirect_routes.path LIKE
'foobar/%';
QUERY PLAN
-----------------------------------------------------------------------------------
Seq Scan on redirect_routes (cost=0.00..1776.23 rows=5 width=4)
Filter: (((path)::text = 'foobar'::text) OR ((path)::text ~~
'foobar/%'::text))
(2 rows)
The database uses a sequential scan even though both of the sides of
that OR have valid indexes that can satisfy them (and for much lower
costs):
=> explain SELECT 1 AS one FROM "redirect_routes" WHERE
redirect_routes.path = 'foobar' ;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
Index Only Scan using index_redirect_routes_on_path_text_pattern_ops
on redirect_routes (cost=0.41..4.43 rows=1 width=4)
Index Cond: (path = 'foobar'::text)
(2 rows)
=> explain SELECT 1 AS one FROM "redirect_routes" WHERE
redirect_routes.path LIKE 'foobar/%';
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
Index Only Scan using index_redirect_routes_on_path_text_pattern_ops
on redirect_routes (cost=0.41..4.44 rows=4 width=4)
Index Cond: ((path ~>=~ 'foobar/'::text) AND (path ~<~ 'foobar0'::text))
Filter: ((path)::text ~~ 'foobar/%'::text)
(3 rows)
I'm guessing the LIKE optimization isn't clever enough to kick in when
it's buried under an OR? Does it only kick in at the top level of the
quals?
--
greg