如果where子句不匹配行,则post postgresql查询速度慢

时间:2011-04-11 15:08:21

标签: postgresql

我在PostgreSQL 9.0.3数据库中有一个简单的表,用于保存从风力发电机控制器轮询的数据。每行代表特定时间特定传感器的值。目前该表有大约90M行:

wtdata=> \d integer_data
          Table "public.integer_data"
 Column |           Type           | Modifiers 
--------+--------------------------+-----------
 date   | timestamp with 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)

我需要的一个查询是查找变量上次更新的时间:

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

在搜索表中存在的变量时,此查询正常工作:

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

但是,如果我尝试搜索表中不存在的变量,查询会挂起(或者需要的时间比我耐心的时间长):

select max(date) from integer_data where name = 'Message';

我让查询运行了几个小时,有时甚至几天都没有结束。表中没有名称='Message'的行:

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

我不明白为什么一个查询很快而另一个需要永远。由于某种原因,查询是否被迫以某种方式扫描整个表?

wtdata=> explain select max(date) from integer_data where 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 IS NOT NULL) AND ((name)::text = 'Message'::text))
(5 rows)

以下是快速查询的查询计划:

wtdata=> explain select max(date) from integer_data where 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 IS NOT NULL) AND ((name)::text = 'STATUS_OF_OUTPUTS_UINT16'::text))
(5 rows)

1 个答案:

答案 0 :(得分:1)

将主键更改为(姓名,日期)。