2010-05-25 3 views
2

HIПростой агрегирующий запрос очень медленный в PostgreSql, любой способ улучшить?

У меня есть таблица, которая хранит файлы и их типы, такие как

CREATE TABLE files (
    id   SERIAL PRIMARY KEY, 
    name  VARCHAR(255), 
    filetype VARCHAR(255), 
    ... 
); 

и другой таблицы для проведения свойства файла, такие как

CREATE TABLE properties (
    id   SERIAL PRIMARY KEY, 
    file_id  INTEGER CONSTRAINT fk_files REFERENCES files(id), 
    size  INTEGER, 
    ... // other property fields 
); 

file_id поле имеет индекс.

Таблица файлов имеет около 800 тыс. Строк, а таблица свойств около 200 тыс. (Не все файлы обязательно имеют/нуждаются в свойствах).

Я хочу выполнить агрегирование запросов, например, найти средний размер и стандартное отклонение для всех типов файлов. Но это очень медленно - около 70 секунд для последнего запроса. Я понимаю, что это требует последовательного сканирования, но все же это кажется слишком большим. Вот запрос

SELECT f.filetype, avg(size), stddev(size) FROM files as f, properties as pr 
WHERE f.id = pr.file_id GROUP BY f.filetype; 

и объяснить

HashAggregate (cost=140292.20..140293.94 rows=116 width=13) (actual time=74013.621..74013.954 rows=110 loops=1) 
    -> Hash Join (cost=6780.19..138945.47 rows=179564 width=13) (actual time=1520.104..73156.531 rows=179499 loops=1) 
     Hash Cond: (f.id = pr.file_id) 
     -> Seq Scan on files f (cost=0.00..108365.41 rows=1140941 width=9) (actual time=0.998..62569.628 rows=805270 loops=1) 
     -> Hash (cost=3658.64..3658.64 rows=179564 width=12) (actual time=1131.053..1131.053 rows=179499 loops=1) 
       -> Seq Scan on properties pr (cost=0.00..3658.64 rows=179564 width=12) (actual time=0.753..557.171 rows=179574 loops=1) 
Total runtime: 74014.520 ms 

Любые идеи, почему это так медленно/как сделать это быстрее?

ответ

1

ли вы определили оптимальные настройки для параметров сервера, как shared_buffers, work_mem и effective_cache_size? http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server

В частности, я думаю, что work_mem повлияет на то, сколько хэш-таблицы для соединения может храниться в памяти, а не на диске. Кроме того, уменьшенная random_page_cost может повлиять на планировщика на использование соединения объединения вместо этого, чтобы временно отключить «enable_hashjoin» и посмотреть, работает ли этот план, который работает лучше?

1

Я не знаю, о PostgresSQL, но я бы

  • убедитесь filetype имеет индекс, возможно, индекс покрытия на типа файла и ид.
  • пытаются переписать запрос на как этот

SQL Заявление

SELECT f.filetype 
     , avg_size 
     , stddev_size 
FROM files as f 
     INNER JOIN (
      SELECT file_id 
        , avg(size) as avg_size 
        , stddev(size) as stddev_size 
      FROM properties 
      GROUP BY 
        file_id 
     ) p ON p.file_id = f.id 
Смежные вопросы