此查询立即运行:
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运行得如此之慢?
答案 0 :(得分:0)
使用RECHECK进行相对较慢的位图堆扫描 - 请尝试增加work_mem