postgresql - Is there a way to query for an integer value or NULL without using OR? -


i'd query (list of) values or null not use or. reasoning behind trying not use or is, need use index on field speed query.

a simple example illustrate question:

create table fruits (   name text,   quantity integer ); 

(the real table has lots of additional integer columns.)

the query i'm not happy is

select * fruits quantity in (1,2,3,4) or quantity null; 

the query i'm hoping like

select * fruits quantity magic (1,2,3,4,null); 

i'm using postgresql 9.1.

as far can tell docs (e.g. http://www.postgresql.org/docs/9.1/static/functions-comparisons.html) , tests there no way this. i'm hoping 1 of has magic insight.

test table 100k rows:

create table fruits (name text, quantity integer); insert fruits (name, quantity) select left(md5(i::text), 6), generate_series(1, 10000) s(i); 

with plain index on quantity:

create index fruits_index on fruits(quantity); analyze fruits; 

the query or:

explain analyze select * fruits quantity in (1,2,3,4) or quantity null;                                                          query plan                                                          ----------------------------------------------------------------------------------------------------------------------------  bitmap heap scan on fruits  (cost=21.29..34.12 rows=4 width=11) (actual time=0.032..0.032 rows=4 loops=1)    recheck cond: ((quantity = ('{1,2,3,4}'::integer[])) or (quantity null))    ->  bitmapor  (cost=21.29..21.29 rows=4 width=0) (actual time=0.025..0.025 rows=0 loops=1)          ->  bitmap index scan on fruits_index  (cost=0.00..17.03 rows=4 width=0) (actual time=0.019..0.019 rows=4 loops=1)                index cond: (quantity = ('{1,2,3,4}'::integer[]))          ->  bitmap index scan on fruits_index  (cost=0.00..4.26 rows=1 width=0) (actual time=0.004..0.004 rows=0 loops=1)                index cond: (quantity null)  total runtime: 0.089 ms 

without or:

explain analyze select * fruits quantity in (1,2,3,4);                                                       query plan                                                        -----------------------------------------------------------------------------------------------------------------------  index scan using fruits_index on fruits  (cost=0.00..21.07 rows=4 width=11) (actual time=0.026..0.038 rows=4 loops=1)    index cond: (quantity = ('{1,2,3,4}'::integer[]))  total runtime: 0.085 ms 

the coalesce version proposed wildplasser leads sequential scan:

explain analyze select *  fruits coalesce(quantity, -1) in (-1,1,2,3,4);                                              query plan                                               -----------------------------------------------------------------------------------------------------  seq scan on fruits  (cost=0.00..217.50 rows=250 width=11) (actual time=0.023..4.358 rows=4 loops=1)    filter: (coalesce(quantity, (-1)) = ('{-1,1,2,3,4}'::integer[]))    rows removed filter: 9996  total runtime: 4.395 ms 

unless coalesce expression index created:

create index fruits_coalesce_index on fruits(coalesce(quantity, -1)); analyze fruits;  explain analyze select *  fruits coalesce(quantity, -1) in (-1,1,2,3,4);                                                            query plan                                                            --------------------------------------------------------------------------------------------------------------------------------  index scan using fruits_coalesce_index on fruits  (cost=0.00..25.34 rows=5 width=11) (actual time=0.112..0.124 rows=4 loops=1)    index cond: (coalesce(quantity, (-1)) = ('{-1,1,2,3,4}'::integer[]))  total runtime: 0.172 ms 

but still worse plain or query plain index on quantity.


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -