Оптимизация запросов по меткам времени и группированию в PostgreSQL - PullRequest
2 голосов
/ 07 июля 2019

Я хочу запросить мою таблицу со следующей структурой:

               Table "public.company_geo_table"
       Column       |  Type  | Collation | Nullable | Default 
--------------------+--------+-----------+----------+---------
 geoname_id         | bigint |           |          | 
 date               | text   |           |          | 
 cik                | text   |           |          | 
 count              | bigint |           |          | 
 country_iso_code   | text   |           |          | 
 subdivision_1_name | text   |           |          | 
 city_name          | text   |           |          | 
Indexes:
    "cik_country_index" btree (cik, country_iso_code)
    "cik_geoname_index" btree (cik, geoname_id)
    "cik_index" btree (cik)
    "date_index" brin (date)

Я попытался с помощью следующего SQL-запроса, который должен запросить определенный номер CIK во время perid, и сгруппировать поcik с geoname_id (разные области).

select cik, geoname_id, sum(count) as total
from company_geo_table
where cik = '1111111'
and date between '2016-01-01' and '2016-01-10'
group by cik, geoname_id

Результат объяснения показал, что они используют только индекс cik и индекс даты, и не используют индекс cik_geoname.Зачем?Есть ли способ, которым я могу оптимизировать свое решение?Есть новые показатели?Заранее спасибо.

HashAggregate  (cost=117182.79..117521.42 rows=27091 width=47) (actual time=560132.903..560134.229 rows=3552 loops=1)
   Group Key: cik, geoname_id
   ->  Bitmap Heap Scan on company_geo_table  (cost=16467.77..116979.48 rows=27108 width=23) (actual time=6486.232..560114.828 rows=8175 loops=1)
         Recheck Cond: ((date >= '2016-01-01'::text) AND (date <= '2016-01-10'::text) AND (cik = '1288776'::text))
         Rows Removed by Index Recheck: 16621155
         Heap Blocks: lossy=193098
         ->  BitmapAnd  (cost=16467.77..16467.77 rows=27428 width=0) (actual time=6469.640..6469.641 rows=0 loops=1)
               ->  Bitmap Index Scan on date_index  (cost=0.00..244.81 rows=7155101 width=0) (actual time=53.034..53.035 rows=8261120 loops=1)
                     Index Cond: ((date >= '2016-01-01'::text) AND (date <= '2016-01-10'::text))
               ->  Bitmap Index Scan on cik_index  (cost=0.00..16209.15 rows=739278 width=0) (actual time=6370.930..6370.930 rows=676231 loops=1)
                     Index Cond: (cik = '1111111'::text)
 Planning time: 12.909 ms
 Execution time: 560135.432 ms

Ответы [ 2 ]

0 голосов
/ 08 июля 2019

Ваша проблема, кажется, здесь:

Rows Removed by Index Recheck: 16621155
Heap Blocks: lossy=193098

Ваш параметр work_mem слишком низкий, поэтому PostgreSQL не может разместить растровое изображение, содержащее один бит на строку таблицы, поэтому оно уменьшается до одного бита на 8 КБблок.Это означает, что многие ложноположительные попадания должны быть удалены во время этого сканирования кучи растрового изображения.

Попробуйте с более высоким work_mem и посмотрите, не улучшит ли это производительность запроса.

Идеальный индекс будет

CREATE INDEX ON company_geo_table (cik, date);
0 голосов
/ 07 июля 2019

Недостаточная оценка (и, вероятно, значение '1111111' используется слишком часто (я не уверен насчет воздействия, но выглядит так, что cik столбец имеет неправильный тип данных (текст), что может быть причиной (иличастичная причина) плохой оценки.

Bitmap Heap Scan on company_geo_table  (cost=16467.77..116979.48 rows=27108 width=23) (actual time=6486.232..560114.828 rows=8175 loops=1)

Похоже, составной индекс (date, cik) может помочь

...