2014-03-05 4 views
2

Этот запрос побежал мгновенно:.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 работает так медленно?

+0

Первый случай будет посмотреть отчет об уникальном ключе и не придется даже выполнить заказ или ограничения, так как всегда будет один удар, поэтому он должен по праву быть очень быстрым. Сколько хитов вы получаете во втором запросе перед 'distinct on'? –

+0

Ваши запросы отличаются не только «отличными». Ваши предложения и порядок, также и другие. Поэтому первый запрос просто не полезен для сравнения. Для интересующего запроса см. Здесь дополнительную информацию, которую вы должны нам сообщить: http://wiki.postgresql.org/wiki/Slow_Query_Questions – jjanes

+0

Я обновил вопрос использования EXPLAIN ANALYZE – JohnMerlino

ответ

0

Существует относительный медленный Bitmap Heap Scan с еще раз проверьте - пожалуйста, попробуйте увеличить work_mem

+0

Можете ли вы подробнее остановиться на этом? Увеличьте work_mem к чему? – JohnMerlino

+0

Вы должны найти оптимальный (и, возможно, я ошибаюсь). Просто попробуйте: SET work_mem до '800MB'; EXPLAIN ANALYZE ... см. Блог об этой проблеме http://michael.otacoo.com/postgresql-2/postgres-9-4-feature-highlight-lossyexact-pages-for-bitmap-heap-scan/ –

+0

800mb ?? ? Я просто запустил SHOW ALL, чтобы показать настройки параметров времени выполнения. И work_mem в настоящее время установлен в 1mb. Ты думаешь, мне стоит до 800 мб? Это будет огромным увеличением, нет? – JohnMerlino

Смежные вопросы