Slow postgresql query if where clause matches no rows -


i have simple table in postgresql 9.0.3 database holds data polled wind turbine controller. each row represents value of particular sensor @ particular time. table has around 90m rows:

wtdata=> \d integer_data           table "public.integer_data"  column |           type           | modifiers  --------+--------------------------+-----------  date   | timestamp time zone | not null  name   | character varying(64)    | not null  value  | integer                  | not null indexes:     "integer_data_pkey" primary key, btree (date, name)     "integer_data_date_idx" btree (date)     "integer_data_name_idx" btree (name) 

one query need find last time variable updated:

select max(date) integer_data name = '<name of variable>'; 

this query works fine when searching variable exists in table:

wtdata=> select max(date) integer_data name = 'status_of_outputs_uint16';           max            ------------------------  2011-04-11 02:01:40-05 (1 row) 

however, if try , search variable doesn't exist in table, query hangs (or takes longer have patience for):

select max(date) integer_data name = 'message'; 

i've let query run hours , days no end in sight. there no rows in table name = 'message':

wtdata=> select count(*) integer_data name = 'message';  count  -------      0 (1 row) 

i don't understand why 1 query fast , other takes forever. query somehow being forced scan entire table reason?

wtdata=> explain select max(date) integer_data name = 'message';                                                        query plan                                                        ------------------------------------------------------------------------------------------------------------------------  result  (cost=13.67..13.68 rows=1 width=0)    initplan 1 (returns $0)      ->  limit  (cost=0.00..13.67 rows=1 width=8)            ->  index scan backward using integer_data_pkey on integer_data  (cost=0.00..6362849.53 rows=465452 width=8)                  index cond: ((date not null) , ((name)::text = 'message'::text)) (5 rows) 

here's query plan fast query:

wtdata=> explain select max(date) integer_data name = 'status_of_outputs_uint16';                                                         query plan                                                         --------------------------------------------------------------------------------------------------------------------------  result  (cost=4.64..4.65 rows=1 width=0)    initplan 1 (returns $0)      ->  limit  (cost=0.00..4.64 rows=1 width=8)            ->  index scan backward using integer_data_pkey on integer_data  (cost=0.00..16988170.38 rows=3659570 width=8)                  index cond: ((date not null) , ((name)::text = 'status_of_outputs_uint16'::text)) (5 rows) 

change primary key (name,date).


Comments

Popular posts from this blog

php - What is the difference between $_SERVER['PATH_INFO'] and $_SERVER['ORIG_PATH_INFO']? -

fortran - Function return type mismatch -

queue - mq_receive: message too long -