Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / изменить план выполнения запроса / 4 сообщений из 4, страница 1 из 1
09.04.2008, 10:11
    #35244515
Gold_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
изменить план выполнения запроса
Всем доброго дня!

Есть запрос
Код: plaintext
1.
2.
3.
4.
5.
6.
EXPLAIN ANALYZE
SELECT kod_dok FROM dok.tdok_reg R
WHERE R.nom_reg_dok IN
 ( 
		SELECT  text_delim_to_set::char( 60 ) AS nom_reg FROM spo.text_delim_to_set('|', '22|340|230')
	    ) 

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Hash Join  (cost= 15 . 50 .. 5798 . 23  rows= 2073  width= 4 ) (actual time= 26 . 372 .. 249 . 328  rows= 81  loops= 1 )
  Hash Cond: ("outer".nom_reg_dok = "inner"."?column2?")
  ->  Seq Scan on tdok_reg r  (cost= 0 . 00 .. 4550 . 86  rows= 161486  width= 68 ) (actual time= 0 . 016 .. 126 . 051  rows= 161486  loops= 1 )
  ->  Hash  (cost= 15 . 50 .. 15 . 50  rows= 200  width= 32 ) (actual time= 0 . 138 .. 0 . 138  rows= 0  loops= 1 )
        ->  HashAggregate  (cost= 15 . 00 .. 15 . 50  rows= 200  width= 32 ) (actual time= 0 . 130 .. 0 . 134  rows= 3  loops= 1 )
              ->  Function Scan on text_delim_to_set  (cost= 0 . 00 .. 12 . 50  rows= 1000  width= 32 ) (actual time= 0 . 118 .. 0 . 121  rows= 3  loops= 1 )
Total runtime:  249 . 429  ms


После
Код: plaintext
1.
SET enable_seqscan to  off;

Код: plaintext
1.
2.
3.
4.
5.
6.
Nested Loop  (cost= 15 . 00 .. 8742 . 59  rows= 2073  width= 4 ) (actual time= 0 . 130 .. 0 . 436  rows= 81  loops= 1 )
  ->  HashAggregate  (cost= 15 . 00 .. 15 . 50  rows= 200  width= 32 ) (actual time= 0 . 101 .. 0 . 107  rows= 3  loops= 1 )
        ->  Function Scan on text_delim_to_set  (cost= 0 . 00 .. 12 . 50  rows= 1000  width= 32 ) (actual time= 0 . 091 .. 0 . 094  rows= 3  loops= 1 )
  ->  Index Scan using i_tdok_reg_tmp on tdok_reg r  (cost= 0 . 00 .. 43 . 48  rows= 10  width= 68 ) (actual time= 0 . 019 .. 0 . 074  rows= 27  loops= 3 )
        Index Cond: (r.nom_reg_dok = "outer"."?column2?")
Total runtime:  0 . 516  ms

Как бы загнать под второй план, не используя SET enable_seqscan to off ?
p.s.
функция text_delim_to_set возращает SETOF, например для запроса:
Код: plaintext
1.
SELECT  text_delim_to_set::char( 60 ) AS nom_reg FROM spo.text_delim_to_set('|', '22|340|230')
результат будет такой
Код: plaintext
1.
2.
3.
 22 
 340 
 230 
...
Рейтинг: 0 / 0
09.04.2008, 10:44
    #35244611
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
изменить план выполнения запроса
а вот так что скажет:
Код: plaintext
1.
2.
3.
4.
5.
6.
....
FROM dok.tdok_reg R
INNER JOIN
 ( 
		SELECT  text_delim_to_set::char( 60 ) AS nom_reg FROM spo.text_delim_to_set('|', '22|340|230') 
	    ) AS q
ON R.nom_reg_dok = q.nom_reg
и , заодно, - как объявлена spo.text_delim_to_set() ? как имутабильнная, стейбл-анутая, или волатитльная?
...
Рейтинг: 0 / 0
09.04.2008, 11:19
    #35244727
Gold_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
изменить план выполнения запроса
4321а вот так что скажет:
Код: plaintext
1.
2.
3.
4.
5.
6.
....
FROM dok.tdok_reg R
INNER JOIN
 ( 
		SELECT  text_delim_to_set::char( 60 ) AS nom_reg FROM spo.text_delim_to_set('|', '22|340|230') 
	    ) AS q
ON R.nom_reg_dok = q.nom_reg
и , заодно, - как объявлена spo.text_delim_to_set() ? как имутабильнная, стейбл-анутая, или волатитльная?

Так попробовал в певую очередь
получилось следующее
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Merge Join  (cost= 41392 . 58 .. 55530 . 12  rows= 807431  width= 144 ) (actual time= 4764 . 408 .. 4806 . 669  rows= 81  loops= 1 )
  Merge Cond: ("outer".text_delim_to_set = "inner"."?column15?")
  ->  Sort  (cost= 62 . 33 .. 64 . 83  rows= 1000  width= 32 ) (actual time= 0 . 105 .. 0 . 106  rows= 3  loops= 1 )
        Sort Key: text_delim_to_set.text_delim_to_set
        ->  Function Scan on text_delim_to_set  (cost= 0 . 00 .. 12 . 50  rows= 1000  width= 32 ) (actual time= 0 . 090 .. 0 . 092  rows= 3  loops= 1 )
  ->  Sort  (cost= 41330 . 25 .. 41733 . 96  rows= 161486  width= 112 ) (actual time= 4700 . 924 .. 4753 . 445  rows= 73946  loops= 1 )
        Sort Key: (r.nom_reg_dok)::text
        ->  Seq Scan on tdok_reg r  (cost= 0 . 00 .. 4550 . 86  rows= 161486  width= 112 ) (actual time= 0 . 021 .. 489 . 617  rows= 161486  loops= 1 )
Total runtime:  5018 . 444  ms
функция имутабильнная


после изменения
statistics_target = 1000 для столбцов таблицы и последующим analyze план стал выбираться "правильный"
...
Рейтинг: 0 / 0
09.04.2008, 11:24
    #35244744
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
изменить план выполнения запроса
Gold_-> Function Scan on text_delim_to_set (rows=1000) (actual rows=3)Проблема в неправильной оценке постгресом кол-ва строк, возвращаемых функцией. В новой версии постгреса при создании функции можно указать параметры "ROWS result_rows" и "COST execution_cost", которые будет использовать постгрес для оценки при выборе плана. В вашей старой версии такой возможности нет.

Нашел мое письмо в рассылку четырехлетней давности, то есть постгрес тогда был старый, правда его кажется не зааппрувили. У нас была похожая проблема. Решили кажется заменой в исходниках глобальной константы 1000 на 20, так как все используемые у нас функции выдают примерно столько строк.

There is "rel->tuples = 1000" hardcoded in the set_function_size_estimates() from backend/optimizer/path/costsize.c. But in my case function glb_get() returns as usual 10 - 30 rows. It seems that if planner would have correct idea about this, it chooses another plan using Nested Loops.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / изменить план выполнения запроса / 4 сообщений из 4, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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