postgresql SELECT DISTINCT ON运行速度很慢

时间:2014-03-05 19:31:38

标签: postgresql

此查询立即运行:

mydb=# SELECT reports.* FROM reports WHERE reports.id = 9988 ORDER BY time DESC LIMIT 1;

这个查询需要33秒才能运行(我在这里只选择了带有unit_id 9988的报告。如果不是数千,我可能会有数百个。)

(更新:这是使用EXPLAIN ANALYZIE的结果):

mydb=# EXPLAIN ANALYZE SELECT DISTINCT ON (unit_id) r.* FROM reports r WHERE r.unit_id IN (3007, 3011, 6193) ORDER BY unit_id, time DESC;
                                                                            QUERY PLAN                                                                             
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Unique  (cost=1377569.23..1381106.10 rows=11 width=155) (actual time=97175.381..97710.369 rows=3 loops=1)
   ->  Sort  (cost=1377569.23..1379337.66 rows=707375 width=155) (actual time=97175.379..97616.039 rows=764509 loops=1)
         Sort Key: unit_id, "time"
         Sort Method:  external merge  Disk: 92336kB
         ->  Bitmap Heap Scan on reports r  (cost=20224.85..1142005.76 rows=707375 width=155) (actual time=12396.930..94097.890 rows=764509 loops=1)
               Recheck Cond: (unit_id = ANY ('{3007,3011,6193}'::integer[]))
               ->  Bitmap Index Scan on index_reports_on_unit_id  (cost=0.00..20048.01 rows=707375 width=0) (actual time=12382.176..12382.176 rows=764700 loops=1)
                     Index Cond: (unit_id = ANY ('{3007,3011,6193}'::integer[]))
 Total runtime: 97982.363 ms
(9 rows)

报告表的架构如下:

mydb=# \d+ reports
                                                    Table "public.reports"
     Column     |            Type             |                      Modifiers                       | Storage  | Description 
----------------+-----------------------------+------------------------------------------------------+----------+-------------
 id             | integer                     | not null default nextval('reports_id_seq'::regclass) | plain    | 
 unit_id        | integer                     | not null                                             | plain    | 
 time_secs      | integer                     | not null                                             | plain    | 
 time           | timestamp without time zone |                                                      | plain    | 
 latitude       | numeric(15,10)              | not null                                             | main     | 
 longitude      | numeric(15,10)              | not null                                             | main     | 
 speed          | integer                     |                                                      | plain    | 
 io             | integer                     |                                                      | plain    | 
 msg_type       | integer                     |                                                      | plain    | 
 msg_code       | integer                     |                                                      | plain    | 
 signal         | integer                     |                                                      | plain    | 
 cellid         | integer                     |                                                      | plain    | 
 lac            | integer                     |                                                      | plain    | 
 processed      | boolean                     | default false                                        | plain    | 
 created_at     | timestamp without time zone |                                                      | plain    | 
 updated_at     | timestamp without time zone |                                                      | plain    | 
 street         | character varying(255)      |                                                      | extended | 
 county         | character varying(255)      |                                                      | extended | 
 state          | character varying(255)      |                                                      | extended | 
 postal_code    | character varying(255)      |                                                      | extended | 
 country        | character varying(255)      |                                                      | extended | 
 distance       | numeric                     |                                                      | main     | 
 gps_valid      | boolean                     | default true                                         | plain    | 
 city           | character varying(255)      |                                                      | extended | 
 street_number  | character varying(255)      |                                                      | extended | 
 address_source | integer                     |                                                      | plain    | 
 source         | integer                     | default 0                                            | plain    | 
 driver_id      | integer                     |                                                      | plain    | 
Indexes:
    "reports_pkey" PRIMARY KEY, btree (id)
    "reports_uniqueness_index" UNIQUE, btree (unit_id, "time", latitude, longitude)
    "index_reports_on_address_source" btree (address_source DESC)
    "index_reports_on_driver_id" btree (driver_id)
    "index_reports_on_time" btree ("time")
    "index_reports_on_time_secs" btree (time_secs)
    "index_reports_on_unit_id" btree (unit_id)
Foreign-key constraints:
    "reports_driver_id_fkey" FOREIGN KEY (driver_id) REFERENCES drivers(id)
    "reports_unit_id_fkey" FOREIGN KEY (unit_id) REFERENCES units(id)
Referenced by:
    TABLE "alerts" CONSTRAINT "alerts_report_id_fkey" FOREIGN KEY (report_id) REFERENCES reports(id)
    TABLE "pressure_transmitters" CONSTRAINT "pressure_transmitters_report_id_fkey" FOREIGN KEY (report_id) REFERENCES reports(id)
    TABLE "thermoking" CONSTRAINT "thermoking_report_id_fkey" FOREIGN KEY (report_id) REFERENCES reports(id)
Has OIDs: no

为什么SELECT DISTINCT ON运行得如此之慢?

1 个答案:

答案 0 :(得分:0)

使用RECHECK进行相对较慢的位图堆扫描 - 请尝试增加work_mem