powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / улучшить время выполнения
25 сообщений из 55, страница 1 из 3
улучшить время выполнения
    #38722827
best_time
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет.

PostgreSQL 9.2.8 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit
Имеется большая таблица hotcore.otahotel
Это таблица - партицирована по неделям.
в одной партиции около 67 млн. строк


Агрегирую некоторые данные таким запросом:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
with  t
as
(
select h.id,h.olap_id,h.region_id,city_en
from
public.otahotel h
where olap_id>=1234
order by olap_id
limit 100

),
tt as
(
select t.id,geo.name,region_id,city_en city
from t
join	public.region r
on	t.region_id = r.id
join	static.geo geo
on	geo.id = any(r.geo_id_array)
and geo.id in (1,2)
)
select	'2014-08-04'::date report_period,
			av.otahotel_id,
			tt.region_id,
			tt.city,
			tt.name,
			--av.booking_window bw,
			--av.length_of_stay los,
			hotcore.parity_type(av.*, 'OTA') result,
			count(av.id) checks,
			sum(case when av.otahotel_price != 0 then 1 else 0 end) avail		
		from
		tt
		join	
		hotcore.otahotel av
		on      av.otahotel_id = tt.id
		where	av.report_date >='2014-08-04'
			and av.report_date < '2014-08-11'
		group 	by 1, 2, 3, 4, 5, 6






такой план:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
GroupAggregate  (cost=1952985.69..2121620.44 rows=360000 width=616) (actual time=253060.708..253119.291 rows=97 loops=1)
  Buffers: shared hit=1603 read=48147
  CTE t
    ->  Limit  (cost=0.00..12.01 rows=100 width=43) (actual time=46.722..87.824 rows=100 loops=1)
          Buffers: shared hit=40 read=15
          ->  Index Scan using inx_u_otahotel_olap_id on otahotel h  (cost=0.00..121090.78 rows=1007859 width=43) (actual time=46.720..87.745 rows=100 loops=1)
                Index Cond: (olap_id >= 1234)
                Buffers: shared hit=40 read=15
  CTE tt
    ->  Nested Loop  (cost=0.00..857.24 rows=9 width=584) (actual time=86.658..702.377 rows=100 loops=1)
          Join Filter: (geo.id = ANY (r.geo_id_array))
          Rows Removed by Join Filter: 100
          Buffers: shared hit=287 read=173
          ->  Nested Loop  (cost=0.00..839.49 rows=100 width=589) (actual time=80.549..695.501 rows=100 loops=1)
                Buffers: shared hit=287 read=171
                ->  CTE Scan on t  (cost=0.00..2.00 rows=100 width=552) (actual time=46.725..88.096 rows=100 loops=1)
                      Buffers: shared hit=40 read=15
                ->  Index Scan using region_pkey on region r  (cost=0.00..8.36 rows=1 width=41) (actual time=6.059..6.069 rows=1 loops=100)
                      Index Cond: (id = t.region_id)
                      Buffers: shared hit=247 read=156
          ->  Materialize  (cost=0.00..12.76 rows=2 width=36) (actual time=0.061..0.062 rows=2 loops=100)
                Buffers: shared read=2
                ->  Seq Scan on geo  (cost=0.00..12.75 rows=2 width=36) (actual time=6.094..6.123 rows=2 loops=1)
                      Filter: (id = ANY ('{1,2}'::integer[]))
                      Rows Removed by Filter: 29
                      Buffers: shared read=2
  ->  Sort  (cost=1952116.43..1959619.91 rows=3001390 width=616) (actual time=253059.764..253066.980 rows=48394 loops=1)
        Sort Key: ('2014-08-04'::date), av.otahotel_id, tt.region_id, tt.city, tt.name, (hotcore.parity_type(av.*, 'OTA'::text))
        Sort Method: quicksort  Memory: 8472kB
        Buffers: shared hit=1603 read=48147
        ->  Nested Loop  (cost=0.00..808514.90 rows=3001390 width=616) (actual time=278.289..252390.572 rows=48394 loops=1)
              Buffers: shared hit=1592 read=48147
              ->  CTE Scan on tt  (cost=0.00..0.18 rows=9 width=584) (actual time=86.662..702.723 rows=100 loops=1)
                    Buffers: shared hit=287 read=173
              ->  Append  (cost=0.00..6446.87 rows=1615 width=64) (actual time=78.824..2492.596 rows=484 loops=100)
                    Buffers: shared hit=1101 read=47974
                    ->  Seq Scan on otahotel av  (cost=0.00..0.00 rows=1 width=572) (actual time=0.001..0.001 rows=0 loops=100)
                          Filter: ((report_date >= '2014-08-04'::date) AND (report_date < '2014-08-11'::date) AND (tt.id = otahotel_id))
                    ->  Bitmap Heap Scan on otahotel_2014w32 av  (cost=68.65..6446.87 rows=1614 width=64) (actual time=78.817..2492.307 rows=484 loops=100)
                          Recheck Cond: (otahotel_id = tt.id)
                          Filter: ((report_date >= '2014-08-04'::date) AND (report_date < '2014-08-11'::date))
                          Buffers: shared hit=1101 read=47974
                          ->  Bitmap Index Scan on otahotel_2014w32_otahotel_id_idx  (cost=0.00..68.24 rows=1614 width=0) (actual time=73.506..73.506 rows=484 loops=100)
                                Index Cond: (otahotel_id = tt.id)
                                Buffers: shared hit=185 read=537
Total runtime: 253122.049 ms



Можно как-то улучшить время выполнения.
спасибо.
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38722897
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот план в чуть более удобном виде .

Таблица `otahotel_2014w32` холодная (`Buffers: shared hit=1101 read=47974`), сильно ли меняется время при повторном запуске запроса?

Если заменить именованные подзапросы на обычные (избавиться от `WITH` конструкции), будет ли план лучше?

Слияние циклами в #13 больно дорого выходит. Чтобы подобрать более вменяемый план, поиграйтесь с `enable_*` опциями на уровне сессии. Скажем, будет ли план лучше при
Код: sql
1.
SET enable_nestloop TO off;

?
Мне кажется тут хэширование будет быстрее...
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38722988
Alexius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
best_time,

тут похоже поможет только кластеризация партиций otahotel по otahotel_id, чтобы с диска меньше читать. но другие запросы могут замедлиться.
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38723001
/\/\/\/\/\/\/\
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
best_time,

Приведите план запроса (ну и результат):

Код: sql
1.
2.
3.
4.
5.
SELECT
  COUNT(*)
FROM hotcore.otahotel av
WHERE av.report_date >='2014-08-04'
  AND av.report_date < '2014-08-11'
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38723614
best_time
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
/\/\/\/\/\/\/\,
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Aggregate  (cost=5091293.21..5091293.22 rows=1 width=0) (actual time=104026.977..104026.977 rows=1 loops=1)
  Buffers: shared hit=148549 read=3775537
  ->  Append  (cost=0.00..4924549.33 rows=66697556 width=0) (actual time=0.016..97824.052 rows=65288691 loops=1)
        Buffers: shared hit=148549 read=3775537
        ->  Seq Scan on otahotel av  (cost=0.00..0.00 rows=1 width=0) (actual time=0.001..0.001 rows=0 loops=1)
              Filter: ((report_date >= 2014-08-04::date) AND (report_date < 2014-08-11::date))
        ->  Seq Scan on otahotel_2014w32 av  (cost=0.00..4924549.33 rows=66697555 width=0) (actual time=0.014..89998.231 rows=65288691 loops=1)
              Filter: ((report_date >= 2014-08-04::date) AND (report_date < 2014-08-11::date))
              Buffers: shared hit=148549 read=3775537
Total runtime: 104027.062 ms

результат 65288691
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38723774
best_time
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovТаблица `otahotel_2014w32` холодная (`Buffers: shared hit=1101 read=47974`), сильно ли меняется время при повторном запуске запроса?

теплая работаем заметно лучше, но при работе в кеш она не попадает

vyegorovЕсли заменить именованные подзапросы на обычные (избавиться от `WITH` конструкции), будет ли план лучше?


Попробовал. Вроде получше. Почему? )

такой план (меняю id'шники, паритции - моделирую холодную работу
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
GroupAggregate  (cost=1256835.03..2059817.12 rows=2817481 width=110) (actual time=133104.569..133174.068 rows=69 loops=1)
  Buffers: shared hit=2511 read=88374
  ->  Sort  (cost=1256835.03..1263878.73 rows=2817481 width=110) (actual time=133103.315..133110.089 rows=89284 loops=1)
        Sort Key: ('2014-08-04'::date), av.otahotel_id, h.region_id, h.city_en, geo.name, (hotcore.parity_type(av.*, 'OTA'::text))
        Sort Method: quicksort  Memory: 16927kB
        Buffers: shared hit=2511 read=88374
        ->  Nested Loop  (cost=0.00..791286.15 rows=2817481 width=110) (actual time=174.984..131925.536 rows=89284 loops=1)
              Buffers: shared hit=2511 read=88374
              ->  Nested Loop  (cost=0.00..868.26 rows=9 width=71) (actual time=0.067..3.873 rows=100 loops=1)
                    Join Filter: (geo.id = ANY (r.geo_id_array))
                    Rows Removed by Join Filter: 100
                    Buffers: shared hit=658
                    ->  Nested Loop  (cost=0.00..850.50 rows=100 width=76) (actual time=0.049..3.240 rows=100 loops=1)
                          Buffers: shared hit=656
                          ->  Limit  (cost=0.00..12.01 rows=100 width=43) (actual time=0.028..0.498 rows=100 loops=1)
                                Buffers: shared hit=54
                                ->  Index Scan using inx_u_otahotel_olap_id on otahotel h  (cost=0.00..121090.78 rows=1007859 width=43) (actual time=0.027..0.413 rows=100 loops=1)
                                      Index Cond: (olap_id >= 1234)
                                      Buffers: shared hit=54
                          ->  Index Scan using region_pkey on region r  (cost=0.00..8.36 rows=1 width=41) (actual time=0.015..0.024 rows=1 loops=100)
                                Index Cond: (id = h.region_id)
                                Buffers: shared hit=602
                    ->  Materialize  (cost=0.00..12.76 rows=2 width=36) (actual time=0.000..0.002 rows=2 loops=100)
                          Buffers: shared hit=2
                          ->  Seq Scan on geo  (cost=0.00..12.75 rows=2 width=36) (actual time=0.010..0.030 rows=2 loops=1)
                                Filter: (id = ANY ('{1,2}'::integer[]))
                                Rows Removed by Filter: 29
                                Buffers: shared hit=2
              ->  Append  (cost=0.00..9536.01 rows=2484 width=65) (actual time=72.658..1291.838 rows=893 loops=100)
                    Buffers: shared hit=1853 read=88374
                    ->  Seq Scan on otahotel av  (cost=0.00..0.00 rows=1 width=572) (actual time=0.001..0.001 rows=0 loops=100)
                          Filter: ((report_date >= '2014-06-30'::date) AND (report_date < '2014-07-07'::date) AND (h.id = otahotel_id))
                    ->  Bitmap Heap Scan on otahotel_2014w27 av  (cost=94.11..9536.01 rows=2483 width=65) (actual time=72.651..1291.416 rows=893 loops=100)
                          Recheck Cond: (otahotel_id = h.id)
                          Filter: ((report_date >= '2014-06-30'::date) AND (report_date < '2014-07-07'::date))
                          Buffers: shared hit=1853 read=88374
                          ->  Bitmap Index Scan on otahotel_2014w27_otahotel_id_idx  (cost=0.00..93.49 rows=2483 width=0) (actual time=67.884..67.884 rows=893 loops=100)
                                Index Cond: (otahotel_id = h.id)
                                Buffers: shared hit=190 read=815
Total runtime: 133175.297 ms



авторСлияние циклами в #13 больно дорого выходит. Чтобы подобрать более вменяемый план, поиграйтесь с `enable_*` опциями на уровне сессии. Скажем, будет ли план лучше при
Код: sql
1.
SET enable_nestloop TO off;

?


Код: sql
1.
2.
SET enable_nestloop TO off;
SET enable_bitmapscan TO off;


это пробовал - иногда чуть лучше

Alexiusbest_time,

тут похоже поможет только кластеризация партиций otahotel по otahotel_id, чтобы с диска меньше читать. но другие запросы могут замедлиться.

оставлю пока "про запас"
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38723963
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
best_timevyegorovЕсли заменить именованные подзапросы на обычные (избавиться от `WITH` конструкции), будет ли план лучше?


Попробовал. Вроде получше. Почему?

Ничего в целом не поменялось.
“Получше” потому, что `WITH` конструкции имеют защиту от оптимизаций. При переписывании с обычными подзапросами у оптимизатора развязаны руки на трансформацию запросов, проталкивание предикатов и другие плюшки.

best_timevyegorovСлияние циклами в #13 больно дорого выходит. Чтобы подобрать более вменяемый план, поиграйтесь с `enable_*` опциями на уровне сессии. Скажем, будет ли план лучше при
Код: sql
1.
SET enable_nestloop TO off;

?


Код: sql
1.
2.
SET enable_nestloop TO off;
SET enable_bitmapscan TO off;


это пробовал - иногда чуть лучше

А были ли варианты когда Hash Join использовался? Можно пример?

Ну а таблица остается “холодной” при использовании SeqScan из-за особенностей работы с кэшем. Чтобы избежать его “вымывания” для SeqScan-ов выделяется маленькая часть кэша, которая используется в цикле ( тут, стр. 10 ).

И еще — что возвращает такой запрос?
Код: sql
1.
2.
3.
SELECT * FROM pg_stat_user_tables
 WHERE relname IN ('otahotel','otahotel_2014w32','otahotel_2014w27','region')
 ORDER BY schemaname,relname;
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724160
--поправил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov,
судя по запросу вы зря ударились оптимизировать джойн до свёртки
похоже просто надо переписать на джойн после свёртки
поскольку со стороны tt тянутся поля однозначно соответствующие tt.id

будет свертка (агрегат) по полному скану -- что стоит, как описал автор, 104027.062 ms (что вдвое быстрее)
+ джойн коротких таблиц.

-------------------

если же автор хочет насладиться преимуществом limit 100, то ему вот это надо ускорять

Код: sql
1.
2.
3.
4.
                    ->  Bitmap Heap Scan on otahotel_2014w32 av  (cost=68.65..6446.87 rows=1614 width=64) (actual time=78.817..2492.307 rows=484 loops=100)
                          Recheck Cond: (otahotel_id = tt.id)
                          Filter: ((report_date >= '2014-08-04'::date) AND (report_date < '2014-08-11'::date))
                          Buffers: shared hit=1101 read=47974




-- расскажите нам, что это и зачем оно тут, если уже явно всё, какбе, отыскано "внутри", причем много дешевле:
Код: sql
1.
2.
3.
                          ->  Bitmap Index Scan on otahotel_2014w32_otahotel_id_idx  (cost=0.00..68.24 rows=1614 width=0) (actual time=73.506..73.506 rows=484 loops=100)
                                Index Cond: (otahotel_id = tt.id)
                                Buffers: shared hit=185 read=537



-- т.е. есть подозрение, что пройти рекурсивно по 100 id из tt "вручную" (в WITH RECURSIVE) будет много дешевле.
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724178
--поправил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ЗЫ, если лениво переписывать -- есть подозрение, что индекс типа otahotel_2014w32_otahotel_id_report_date_idx
(otahotel_id,report_date) вправят оптимайзеру мозги взад, но надо проверять
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724204
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--поправилvyegorov,
судя по запросу вы зря ударились оптимизировать джойн до свёртки

-------------------

если же автор хочет насладиться преимуществом limit 100, то ему вот это надо ускорять

Код: sql
1.
2.
3.
4.
                    ->  Bitmap Heap Scan on otahotel_2014w32 av  (cost=68.65..6446.87 rows=1614 width=64) (actual time=78.817..2492.307 rows=484 loops=100)
                          Recheck Cond: (otahotel_id = tt.id)
                          Filter: ((report_date >= '2014-08-04'::date) AND (report_date < '2014-08-11'::date))
                          Buffers: shared hit=1101 read=47974





Вот ради оптимизации `loops=100` и пытаюсь понять, почему оптимизатор выбирает цикл, а не хэш.
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724220
/\/\/\/\/\/\
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
--поправил... лениво переписывать...

Не уверен, что переписывать нужно много:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
WITH
...
tt AS (
...
),
av AS (
SELECT
  *
FROM hotcore.otahotel av
WHERE av.report_date >='2014-08-04'
  AND av.report_date < '2014-08-11'
)
select	'2014-08-04'::date report_period,
			av.otahotel_id,
			tt.region_id,
			tt.city,
			tt.name,
			--av.booking_window bw,
			--av.length_of_stay los,
			hotcore.parity_type(av.*, 'OTA') result,
			count(av.id) checks,
			sum(case when av.otahotel_price != 0 then 1 else 0 end) avail		
		from
		tt
		join av on      av.otahotel_id = tt.id

		where	av.report_date >='2014-08-04'
			and av.report_date < '2014-08-11'
		group 	by 1, 2, 3, 4, 5, 6



Как-то так.
Но выбор во временные данные 65 млн строк меня смущает.
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724252
--поправил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov,
не понял, зачем там хеш. тогда уж свернуть сначала, а потом джойнить. получите то, чего хотите, без затрат на джойн (это что, всю миллионную захешировать, потом поджойнить, и результат свернуть ? боец борется за разницу меж лямами [65288691, но последовательно] и килами [48394, но произвольно] )


-- тут интересно то, что эти записи (484) оптимайзер находит (внутри, по индексу) практически без затрат времени (пусть и лупнув 100) -- см. этап 18 плана по ссылке

а затем (снаружи) зачем то делает над ними же 17.
Bitmap Heap Scan on otahotel_2014w32 av
но уже теряя кучу (втрое) времени
Код: sql
1.
2.
3.
4.
 (actual time=78.817..2492.307 rows=484 loops=100)

    Recheck Cond: (otahotel_id = tt.id)
    Filter: ((report_date >= '2014-08-04'::date) AND (report_date < '2014-08-11'::date))


-- я не силён в таких тонкостях -- напрочь не понимаю, чем оно тут занимается. фильтровать оно могло и на проходе 18. считай бесплатно.

PS -- если бы в 18 было написано IOS -- я бы хоть что-то понял
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724265
--поправил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
/\/\/\/\/\/\,
не, я не про то.
я про 2 абсолютно разные альтернативы

1. свернуть все 65 лямов на проходе (100 секунд --см выше), потом поджойниться - выиграем вполовину, но никак не больше

или (совсем другое)

2. взять в CTE 100 id, и для каждого из них в конструкции with recursive взять свой агрегат (что оптимайзер [+-километр] и должен делать, но я как-то это плохо читаю).
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724280
--поправил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторно уже теряя кучу (втрое в 30 -- 2400 vs 80) времени
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724303
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--поправилvyegorov,
не понял, зачем там хеш. тогда уж свернуть сначала, а потом джойнить. получите то, чего хотите, без затрат на джойн (это что, всю миллионную захешировать, потом поджойнить, и результат свернуть ? боец борется за разницу меж лямами [65288691, но последовательно] и килами [48394, но произвольно] )
Хэшируется меньшая сторона, потом делается проход по большей. В данном случае сделать хэш для 100 записей из подзапроса и потом один раз пройти SeqScan-ом по 67 лимонам мне кажется будет быстрым, в пределах тех же 100 секунд. Я вижу 2 причины почему не используется хэш:
невозможно архитектурно (внутренние ограничения СУБД), но это гипотеза, точно не знаю что может быть такого;

перекос в статистиках/недостаточный размер гистограммы. Тут можно что-то крутить.

Что же касается “переписать” запрос — полностью согласен. Но хочется же разобраться в чем тут дело...

--поправил-- тут интересно то, что эти записи (484) оптимайзер находит (внутри, по индексу) практически без затрат времени (пусть и лупнув 100) -- см. этап 18 плана по ссылке

а затем (снаружи) зачем то делает над ними же 17.
Bitmap Heap Scan on otahotel_2014w32 av
но уже теряя кучу (втрое) времени
Код: sql
1.
2.
3.
4.
 (actual time=78.817..2492.307 rows=484 loops=100)

    Recheck Cond: (otahotel_id = tt.id)
    Filter: ((report_date >= '2014-08-04'::date) AND (report_date < '2014-08-11'::date))


-- я не силён в таких тонкостях -- напрочь не понимаю, чем оно тут занимается. фильтровать оно могло и на проходе 18. считай бесплатно.

PS -- если бы в 18 было написано IOS -- я бы хоть что-то понял

Это особенности работы BitmapScan-а. Сначала он идет по индексу, но возвращает для каждого блока (8Кб) содержащего искомые значения 1, или 0 в противном случае. Понятно, что после этого надо прочитать такие блоки и вытащить из них записи. Потому и получается всегда 2 (и более) этапа:

сначала несколько Bitmap Index Scan-ов;

наложение битмапов если более 1 индекса на 1-м шаге;

результирующий Bitmap Heap Scan.

Смысл в том, что если несколько индексов реляции подпадают под предикаты, по ним всем делаются проходы (Bitmap Index Scan), затем полученные битмапы логически накладываются (BitmapAnd / BitmapOr) и только потом идет обращение к записям (Bitmap Heap Scan) — быстрее выходит. Для единственного индекса такой проход выбирается, если селективность не очень. Тут подробнее .
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724335
--поправил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov,

1. люди, пишущие pdf идут строго лесом. (я не типография)

2. т.е. вы хотите сказать, что 18 -- это реально IOS ?
а потом BitmapOr с реальным произвольным доступом к 48000 записям (страницам) жрет 240 сек ? по ~5 ms на доступ? [200 в секунду -- 1200 в минуту - не маловато будет? или я где-то провираюсь ?)
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724343
--поправил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
--поправилvyegorov,

1. люди, пишущие pdf идут строго лесом. (я не типография)

2. т.е. вы хотите сказать, что 18 -- это реально IOS ?
а потом BitmapOr с реальным произвольным доступом к 48000 записям (страницам) жрет 240 сек ? по ~5 ms на доступ? [200 в секунду -- 12000 в минуту - не маловато будет? или я где-то провираюсь ?)
бгг.
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724366
--поправил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
там при ожиданиях много хуже 48к
авторrows=3001390
оптимайзер пускается на NestedLoop
-- имхо у ТС косты переставлены супротив дефолтных. или enable seqscan (и т.п.) в off-е
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724486
best_time
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovИ еще — что возвращает такой запрос?
Код: sql
1.
2.
3.
SELECT * FROM pg_stat_user_tables
 WHERE relname IN ('otahotel','otahotel_2014w32','otahotel_2014w27','region')
 ORDER BY schemaname,relname;



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
   relid    | schemaname |     relname      | seq_scan | seq_tup_read | idx_scan | idx_tup_fetch 
------------+------------+------------------+----------+--------------+----------+---------------
 2520075393 | hotcore    | otahotel         |   227770 |            0 |        7 |             0
 3414794803 | partitions | otahotel_2014w27 |       37 |    124607613 |      155 |       1248182
 3570135254 | partitions | otahotel_2014w32 |       57 |   1105909190 |    76765 |   22468950983
 1586228924 | public     | otahotel         |      498 |    316392933 |  4034473 |       8150453
  367346872 | public     | region           |     1308 |    161067354 | 16604473 |      36259012
(5 строк)

...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724525
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
best_time
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
   relid    | schemaname |     relname      | seq_scan | seq_tup_read | idx_scan | idx_tup_fetch 
------------+------------+------------------+----------+--------------+----------+---------------
 2520075393 | hotcore    | otahotel         |   227770 |            0 |        7 |             0
 3414794803 | partitions | otahotel_2014w27 |       37 |    124607613 |      155 |       1248182
 3570135254 | partitions | otahotel_2014w32 |       57 |   1105909190 |    76765 |   22468950983
 1586228924 | public     | otahotel         |      498 |    316392933 |  4034473 |       8150453
  367346872 | public     | region           |     1308 |    161067354 | 16604473 |      36259012
(5 строк)



Я ожидал увидеть больше колонок: тыц .
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724573
best_time
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov,

там 0 и NULL'ы - все равно важно?
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724622
--поправил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov,
могабыть оно слишком мало ожидает строк от tt ?

Код: sql
1.
2.
CTE tt
    ->  Nested Loop  (cost=0.00..857.24 rows=9 width=584) (actual time=86.658..702.377 rows=100 loops=1)


причем (что не очевидно, но вероятно) -- похоже geo.name можно извлечь уже в t коррелированным полем (или ТС ожидает там размножения имен ?) -- тогда оптимизатор будет знать, что предстоит искать в big table по 100 а не по 9 id-кам.


но то, что оно планирует Nested Loop при ожидании 3001390 rows
Код: sql
1.
Nested Loop  (cost=0.00..808514.90 rows=3001390 width=616)

-- кажется сипанным. что то подкручено с cost-ами ?
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724631
--поправил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
best_time,

SHOW random_page_cost ; ?
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724636
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
best_timevyegorov,

там 0 и NULL'ы - все равно важно?

Хм, если там NULL-ы, то у меня вопросы:
как статистики собираются в системе вообще?

что выдаст такой запрос
Код: sql
1.
select name,setting,source from pg_settings where name ~ '^autovacuum|cost|enable';



как изменится план после запуска следующих команд
Код: sql
1.
2.
3.
4.
5.
VACUUM ANALYZE partitions.otahotel_2014w27;
VACUUM ANALYZE partitions.otahotel_2014w32;
VACUUM ANALYZE hotcore.otahotel;
VACUUM ANALYZE public.otahotel;
VACUUM ANALYZE public.region;
...
Рейтинг: 0 / 0
улучшить время выполнения
    #38724664
best_time
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
--поправилbest_time,

SHOW random_page_cost ; ?
4
...
Рейтинг: 0 / 0
25 сообщений из 55, страница 1 из 3
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / улучшить время выполнения
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]