首先选择太慢

时间:2016-03-31 02:13:27

标签: postgresql

运行机器(centos release 6.7(Final))在4G上面postgresql-9.4,有一个分区表,每个分区表中大约有10万条记录在选择,第一个查询查询特别慢,大约15秒,但第二次在OK,我不知道为什么。需要帮助。

以下是我的SQL和执行计划

     explain SELECT
      pos_uuid,
pos_bus_uuid,
pos_gather_time,
pos_real_time_status,
pos_odometer,
pos_drv_ic_card
FROM   t_bus_position_20160306_20160308  WHERE  pos_gather_time >=  '2016-03-06 00:08:00' AND pos_gather_time <='2016-03-06 23:59:59' and  pos_is_offset = 't'  and pos_bus_uuid ='b478193370f24b8f9fe1' ORDER BY pos_gather_time ;
                                                                                                                    QUERY PLAN                   

----------------------------------------------- -------------------------------------------------- --------------------------------------------

Sort  (cost=94141.44..94176.57 rows=14052 width=145)
   Sort Key: pos_gather_time
   ->  Bitmap Heap Scan on t_bus_position_20160306_20160308  (cost=1039.36..93173.36 rows=14052 width=145)
         Recheck Cond: (((pos_bus_uuid)::text = 'b478193370f24b8f9fe1'::text) AND (pos_gather_time >= '2016-03-06 00:08:00'::timestamp withou
t time zone) AND (pos_gather_time <= '2016-03-06 23:59:59'::timestamp without time zone))
         Filter: pos_is_offset
         ->  Bitmap Index Scan on idx_check_index  (cost=0.00..1035.85 rows=28103 width=0)
               Index Cond: (((pos_bus_uuid)::text = 'b478193370f24b8f9fe1'::text) AND (pos_gather_time >= '2016-03-06 00:08:00'::timestamp wi
thout time zone) AND (pos_gather_time <= '2016-03-06 23:59:59'::timestamp without time zone))

It is several important parameters of the configuration file
shared_buffers =2GB 
huge_pages = try                            
temp_buffers = 16MB                     
work_mem =128MB         
maintenance_work_mem =512MB     
max_stack_depth = 8MB           
dynamic_shared_memory_type = posix  
checkpoint_segments = 32    
max_connections = 100
seq_page_cost = 1.0         
random_page_cost = 4        
cpu_tuple_cost = 0.01       
cpu_index_tuple_cost = 0.005        
cpu_operator_cost = 0.0025      
effective_cache_size = 2GB  



      \d t_bus_position_20160303_20160305
           Table "public.t_bus_position_20160303_20160305"
         Column         |              Type              | Modifiers 
------------------------+--------------------------------+-----------
 pos_uuid               | character varying(20)          | not null
 pos_line_uuid          | character varying(20)          | 
 pos_line_type          | character varying(20)          | 
 pos_bus_uuid           | character varying(20)          | 
 pos_dev_uuid           | character varying(20)          | 
 pos_sta_uuid           | character varying(20)          | 
 pos_drv_ic_card        | character varying(30)          | 
 pos_lng                | character varying(30)          | 
 pos_lat                | character varying(30)          | 
 pos_bus_speed          | character varying(20)          | 
 pos_real_time_status   | character varying(20)          | 
 pos_gather_time        | timestamp(6) without time zone | 
 pos_storage_time       | timestamp(6) without time zone | 
 pos_is_offset          | character varying(20)          | 
 pos_is_overspeed       | character varying(1)           | 
 pos_cursor_over_ground | character varying(20)          | 
 pos_all_alarms         | character varying(30)          | 
 pos_is_in_station      | character varying(1)           | 
 pos_closed_alarms      | character varying(30)          | 
 pos_dis_to_pre_i       | integer                        | 
 pos_odometer_i         | bigint                         | 
 pos_relative_location  | real                           | 
 pos_dis_to_pre         | real                           | 
 pos_odometer           | double precision               | 
 pos_gather_date        | date                           | 
Indexes:
    "tp_20160303_20160305_pos_uuid_idx" UNIQUE, btree (pos_uuid)
    "tp_20160303_20160305_pos_bus_gather_date_idx" btree ((pos_bus_uuid::text || extract_date(pos_gather_time)))
    "tp_20160303_20160305_pos_bus_gather_idx" btree (pos_bus_uuid, extract_date(pos_gather_time))
    "tp_20160306_20160308_pos_bus_gather_time_idx" btree (pos_gather_time, pos_gather_time DESC)
Check constraints:
    "t_bus_position_20160303_20160305_pos_gather_time_check" CHECK (pos_gather_time >= '2016-03-03 00:00:00'::timestamp without time zone AND
 pos_gather_time < '2016-03-06 00:00:00'::timestamp without time zone)
Inherits: t_bus_position


 **This is the is Boolean pos_is_offset implementation plan**
explain    SELECT
pos_uuid,
pos_bus_uuid,
pos_gather_time,
pos_real_time_status,
pos_odometer,
pos_drv_ic_card
FROM   t_bus_position_20160306_20160308  WHERE  pos_gather_time >=  '2016-03-06 00:08:00' AND pos_gather_time <='2016-03-06 23:59:59' and  pos_is_offset = 't'  and pos_bus_uuid ='b478193370f24b8f9fe1' ORDER BY pos_gather_time ;
                                                                                                                QUERY PLAN                   

---------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------
 Sort  (cost=94141.44..94176.57 rows=14052 width=145)
   Sort Key: pos_gather_time
   ->  Bitmap Heap Scan on t_bus_position_20160306_20160308  (cost=1039.36..93173.36 rows=14052 width=145)
         Recheck Cond: (((pos_bus_uuid)::text = 'b478193370f24b8f9fe1'::text) AND (pos_gather_time >= '2016-03-06 00:08:00'::timestamp withou
t time zone) AND (pos_gather_time <= '2016-03-06 23:59:59'::timestamp without time zone))
         Filter: pos_is_offset
         ->  Bitmap Index Scan on idx_check_index  (cost=0.00..1035.85 rows=28103 width=0)
               Index Cond: (((pos_bus_uuid)::text = 'b478193370f24b8f9fe1'::text) AND (pos_gather_time >= '2016-03-06 00:08:00'::timestamp wi
thout time zone) AND (pos_gather_time <= '2016-03-06 23:59:59'::timestamp without time zone))
(7 rows)

1 个答案:

答案 0 :(得分:1)

两件事:

  1. 这里的扰流器看起来像是pos_is_offset列,它是唯一不属于所用索引的字段。这是一个非常重要的查询(足以修改索引并添加该布尔值),这可能有助于加快查询速度。

  2. 第一次运行缓慢,后续运行速度更快的查询清楚地表明正在从磁盘读取表,缓存会影响后续运行的速度。加快查询速度变得非常困难,特别是如果你的RAM +大数据集不足。

  3. 另外,你真的需要输出14k行吗?或者表格不经常ANALYSE'd?如果运行EXPLAIN ANALYSE时的行计数给出的数字太远,那么您可能还需要ANALYSE该表。