powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / не оптимальный план - почему так?
5 сообщений из 5, страница 1 из 1
не оптимальный план - почему так?
    #38542547
Добрый день.

Создаем и наполняем таблицу:

Код: plsql
1.
2.
3.
4.
5.
6.
create table t1 (id int);

insert into t1 (id) 
select round(random() * 10000) from generate_series(1,10000);

vacuum analyze t1;



Смотрим план:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
explain select
  x.id, 
  x.cnt,
  x.cnt,
  x.cnt
from (
  select
    (select count(1) from t1 where t1.id < 100) as cnt,
    id
  from t1
  where t1.id < 200
) x



И видим:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
"Seq Scan on t1  (cost=510.81..680.81 rows=197 width=4)"
"  Filter: (id < 200)"
"  InitPlan 1 (returns $0)"
"    ->  Aggregate  (cost=170.26..170.27 rows=1 width=0)"
"          ->  Seq Scan on t1 t1_1  (cost=0.00..170.00 rows=104 width=0)"
"                Filter: (id < 100)"
"  InitPlan 2 (returns $1)"
"    ->  Aggregate  (cost=170.26..170.27 rows=1 width=0)"
"          ->  Seq Scan on t1 t1_2  (cost=0.00..170.00 rows=104 width=0)"
"                Filter: (id < 100)"
"  InitPlan 3 (returns $2)"
"    ->  Aggregate  (cost=170.26..170.27 rows=1 width=0)"
"          ->  Seq Scan on t1 t1_3  (cost=0.00..170.00 rows=104 width=0)"
"                Filter: (id < 100)"



И видим 3 агрегата, по количеству x.cnt.
Не понятно, почему подзапрос выполняется не один раз, а по количеству полей, его использующих во внешнем селекте.
И как с этим бороться?


Версия постгрес 9.1, на 9.3 то же самое.
...
Рейтинг: 0 / 0
не оптимальный план - почему так?
    #38542609
Sasha Alias
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
медведка_креведкаИ как с этим бороться?


Вынести скалярный подзапрос с аггрегацией во FROM или в WITH
...
Рейтинг: 0 / 0
не оптимальный план - почему так?
    #38542681
медведка_креведкаНе понятно, почему подзапрос выполняется не один раз, а по количеству полей, его использующих во внешнем селекте.Эт как раз таки понятно - оптимизатор раскрыл встроенное представление (внутренний запрос Х) и переписал всю конструкцию таким образом, словно подзапроса "Х" и нет вовсе. Но в этом случае ему ничего не осталось, как выполнить трижды скалярный коррелированный подзапрос в селект-листе получившегося после трансформации запроса.
...
Рейтинг: 0 / 0
не оптимальный план - почему так?
    #38542975
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
медведка_креведка,

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

или (хак но постоянно используемый) добавьте offset 0:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
explain select
  x.id, 
  x.cnt,
  x.cnt,
  x.cnt
from (
  select
    (select count(1) from t1 where t1.id < 100) as cnt,
    id
  from t1
  where t1.id < 200
  [color=red]offset 0[/color]
) x
...
Рейтинг: 0 / 0
не оптимальный план - почему так?
    #38543303
Ясно, понятно.
Во FROM, WITH перенести не проблема, это надуманный запрос для примера. Просто хотелось разобраться.
offset - интересное предложение, спасибо!
Всем спасибо!
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / не оптимальный план - почему так?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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