Этот запрос побежал мгновенно:.PostGreSQL SELECT DISTINCT ON работает очень медленно
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 работает так медленно?
Первый случай будет посмотреть отчет об уникальном ключе и не придется даже выполнить заказ или ограничения, так как всегда будет один удар, поэтому он должен по праву быть очень быстрым. Сколько хитов вы получаете во втором запросе перед 'distinct on'? –
Ваши запросы отличаются не только «отличными». Ваши предложения и порядок, также и другие. Поэтому первый запрос просто не полезен для сравнения. Для интересующего запроса см. Здесь дополнительную информацию, которую вы должны нам сообщить: http://wiki.postgresql.org/wiki/Slow_Query_Questions – jjanes
Я обновил вопрос использования EXPLAIN ANALYZE – JohnMerlino