Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / улучшить время выполнения / 25 сообщений из 55, страница 1 из 3
18.08.2014, 18:05:26
    #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
18.08.2014, 19:19:08
    #38722897
vyegorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
улучшить время выполнения
Вот план в чуть более удобном виде .

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

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

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

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

тут похоже поможет только кластеризация партиций otahotel по otahotel_id, чтобы с диска меньше читать. но другие запросы могут замедлиться.
...
Рейтинг: 0 / 0
18.08.2014, 22:14:52
    #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
19.08.2014, 16:04:42
    #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
19.08.2014, 18:34:10
    #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
20.08.2014, 00:32:19
    #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
20.08.2014, 10:56:05
    #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
20.08.2014, 11:04:26
    #38724178
--поправил
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
улучшить время выполнения
ЗЫ, если лениво переписывать -- есть подозрение, что индекс типа otahotel_2014w32_otahotel_id_report_date_idx
(otahotel_id,report_date) вправят оптимайзеру мозги взад, но надо проверять
...
Рейтинг: 0 / 0
20.08.2014, 11:19:01
    #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
20.08.2014, 11:24:33
    #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
20.08.2014, 11:42:49
    #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
20.08.2014, 11:50:10
    #38724265
--поправил
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
улучшить время выполнения
/\/\/\/\/\/\,
не, я не про то.
я про 2 абсолютно разные альтернативы

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

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

2. взять в CTE 100 id, и для каждого из них в конструкции with recursive взять свой агрегат (что оптимайзер [+-километр] и должен делать, но я как-то это плохо читаю).
...
Рейтинг: 0 / 0
20.08.2014, 12:00:20
    #38724280
--поправил
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
улучшить время выполнения
авторно уже теряя кучу (втрое в 30 -- 2400 vs 80) времени
...
Рейтинг: 0 / 0
20.08.2014, 12:10:40
    #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
20.08.2014, 12:29:39
    #38724335
--поправил
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
улучшить время выполнения
vyegorov,

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

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

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

2. т.е. вы хотите сказать, что 18 -- это реально IOS ?
а потом BitmapOr с реальным произвольным доступом к 48000 записям (страницам) жрет 240 сек ? по ~5 ms на доступ? [200 в секунду -- 12000 в минуту - не маловато будет? или я где-то провираюсь ?)
бгг.
...
Рейтинг: 0 / 0
20.08.2014, 12:44:05
    #38724366
--поправил
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
улучшить время выполнения
там при ожиданиях много хуже 48к
авторrows=3001390
оптимайзер пускается на NestedLoop
-- имхо у ТС косты переставлены супротив дефолтных. или enable seqscan (и т.п.) в off-е
...
Рейтинг: 0 / 0
20.08.2014, 13:52:40
    #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
20.08.2014, 14:15:06
    #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
20.08.2014, 14:51:38
    #38724573
best_time
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
улучшить время выполнения
vyegorov,

там 0 и NULL'ы - все равно важно?
...
Рейтинг: 0 / 0
20.08.2014, 15:14:16
    #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
20.08.2014, 15:18:44
    #38724631
--поправил
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
улучшить время выполнения
best_time,

SHOW random_page_cost ; ?
...
Рейтинг: 0 / 0
20.08.2014, 15:22:14
    #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
20.08.2014, 15:33:29
    #38724664
best_time
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
улучшить время выполнения
--поправилbest_time,

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


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