Улучшение алгоритма на простом взгляде postgresql запрос

Высокий уровень: я могу сделать это order by, group by на основе sum немного быстрее? (PG 8.4, fwiw., на некрошечной таблице.... думают O (миллионы строк)),

Предположим, что у меня была таблица как это:

                                 Table "public.summary"
   Column    |       Type        |                      Modifiers
-------------+-------------------+------------------------------------------------------
 ts          | integer           | not null default nextval('summary_ts_seq'::regclass)
 field1      | character varying | not null
 otherfield  | character varying | not null
 country     | character varying | not null
 lookups     | integer           | not null


Indexes:
    "summary_pk" PRIMARY KEY, btree (ts, field1, otherfield, country)
    "ix_summary_country" btree (country)
    "ix_summary_field1" btree (field1)
    "ix_summary_otherfield" btree (otherfield)
    "ix_summary_ts" btree (ts)

И запрос, который я хочу:

select summary.field1,
    summary.country,
    summary.ts,
    sum(summary.lookups) as lookups,
from summary
where summary.country = 'za' and
    summary.ts = 1275177600
group by summary.field1, summary.country, summary.ts
order by summary.ts, lookups desc, summary.field1
limit 100;

(Английский язык: лучшие 100 field1 в детали (ts, страна), где 'высокопоставленность' является суммой поисков для любой строки соответствия, независимо от значения otherfield),

Есть ли что-нибудь, что я могу действительно сделать для ускорения этого? Алгоритмически это, кажется, полный вид сканирования таблицы вещи, но я мог бы пропускать что-то.

5
задан Gregg Lind 2 July 2010 в 00:25
поделиться

3 ответа

Любой план запроса для этого запроса должен будет сканировать каждую строку, которая соответствует условиям WHERE, объединяя их по условиям группировки, то есть объем работы пропорционален количеству входных строк в группе по, а не количество строк результата.

Самый эффективный план запроса, возможный для такого запроса, - это однократное сканирование индекса. Это должно быть возможно, если вы построите индекс для (страна, ts) в таком порядке; с этим индексом каждый возможный запрос этой формы разрешается в непрерывный диапазон по индексу. Однако для этого по-прежнему потребуется сортировка в памяти - этого можно избежать с другим индексом.

Однако, как говорили другие, лучший вариант - опубликовать план выполнения.

2
ответ дан 15 December 2019 в 00:49
поделиться

Чтобы иметь возможность предложить что-либо, вы должны опубликовать план выполнения запроса.

И "OMG Ponies" прав: limit 100 ограничит общий результат до 100 строк, он не будет работать на отдельных группах!

В Postgres Wiki есть хорошая статья, которая объясняет, как опубликовать вопрос, связанный с медленным запросом:

http://wiki.postgresql.org/wiki/SlowQueryQuestions

1
ответ дан 15 December 2019 в 00:49
поделиться

Индекс на (страна, ts) - лучший вариант (как предлагает Ник Джонсон), и, кроме того, вы можете поднять work_mem , если он не установлен очень высоко. Вы можете УСТАНОВИТЬ это во время выполнения, если это необходимо (и если оно будет очень высоким, рекомендуется). Это поможет сохранить ваши сортировки в памяти, а не на диск (если это произойдет).

Чтобы получить реальную помощь, нам понадобится увидеть EXPLAIN ANALYZE , размещение его на объяснении.depesz.com может сделать его очень удобочитаемым.

1
ответ дан 15 December 2019 в 00:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: