powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Работа планировщика при CTE.
16 сообщений из 16, страница 1 из 1
Работа планировщика при CTE.
    #39749314
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FB3. Давно замечал странности, но как-то выкручивался. Вот пришло время спросить.
Запрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
with q (id_spr) as (
  select c.id_spr
  from sprav e
       inner join sprav d on d.id_spar=e.id_spr
       inner join sprav c on c.id_spar=d.id_spr
  where e.priz_spr=4 and e.s_name='PDCA'
)
select b.id_mdl
from q
     inner join statkit b on b.id_spr=q.id_spr


Результат:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
План
PLAN JOIN (B NATURAL, Q C INDEX (PK_SPRAV), Q D INDEX (PK_SPRAV), Q E INDEX (PK_SPRAV))

------ Информация о производительности ------
Время подготовки запроса = 0ms
Время выполнения запроса = 8s 767ms
Среднее время на получение одной записи = 21,75 ms
Current memory = 58 955 248
Max memory = 69 031 816
Memory buffers = 12 000
Reads from disk to cache = 25 064
Writes from cache to disk = 1
Чтений из кэша = 17 126 758


Запрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
with q (id_spr) as (
  select c.id_spr
  from sprav e
       inner join sprav d on d.id_spar=e.id_spr
       inner join sprav c on c.id_spar=d.id_spr and c.id_spr is not null
  where e.priz_spr=4 and e.s_name='PDCA'
)
select b.id_mdl
from q
     inner join statkit b on b.id_spr=q.id_spr


Результат:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
План
PLAN JOIN (Q E INDEX (I_PRIZ), Q D INDEX (FK_SPRAV_RELATIONS_SPRAV), Q C INDEX (FK_SPRAV_RELATIONS_SPRAV), B INDEX (FK_STATKIT_2))

------ Информация о производительности ------
Время подготовки запроса = 0ms
Время выполнения запроса = 15ms
Среднее время на получение одной записи = 0,04 ms
Current memory = 58 960 960
Max memory = 69 031 816
Memory buffers = 12 000
Reads from disk to cache = 68
Writes from cache to disk = 0
Чтений из кэша = 792


Я воспринимал CTE так. Запрос под with'ом выполняется как бы независимо, основной запрос выполняется потом. Вижу, что не так. Манипуляции с запросами под with'ом и основным приводят к совершенно разным вариантам плана запроса. Второй подзапрос под with'ом ещё усложняет ситуацию. Как уловить взаимосвязь между запросами в CTE? А то получается - подставляю какие-то костыли.
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39749319
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXIЯ воспринимал CTE так. Запрос под with'ом выполняется как бы независимо, основной запрос выполняется потом. Вижу, что не так.Ибо не так.

CTE - это то же самое, что и VIEW, только его объявление не сохраняется в схеме БД.
Тело CTE\VIEW всегда подставляется в основной запрос и рассматривается как единое целое.
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39749679
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Упс. А я рассчитывал тратить чуть менее времени на оптимизацию запросов при использовании CTE.
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39749820
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

не вижу связи
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39749951
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad,

Для оптимизации запроса надо учитывать условия, которые "проваливаются" внутрь вью и цте.
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39749975
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad,

не хотелось бы напрасно дискутировать, Вам видней. Но, ИМХО, как выразился WildSery, это "проваливание" запросов убивает весь цимус СТЕ. Формально функционал поддерживается, а реализация дело десятое.
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39749981
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

По мне так это самое "проваливание" и есть в реализации данного института самое благое. Так же, кстати, как и при использовании VIEW.
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39750000
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

э... может не надо говорить о то что ты не понимаешь?
Проталкивание предикатов это часть оптимизации. Если не хочешь чтобы оно происходило можно подсказать +0 например или задать порядок через left join. Или вообще сделай так чтобы соединение шло hash join, тогда твоя CTE возможно "материализуется".
Кстати в твоём запросе CTE вообще не нужна.
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39750003
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ок, не будем напрасно объяснять, в чём Вы заблуждаетесь
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39750090
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запрос специально упростил. И, ОК, я заблуждаюсь. Но, чтобы получить более-менее приемлемую работу планировщика, приходиться тратить уйму времени на "оптимизацию" запросов, а, фактически, занимаюсь манипулированием джойнами, их порядком, хинтами... Приведённый мной пример показывает, что планировщик без всякой видимой причины пускает запрос не по тому пути. И, да, рассчитывал, что механизм CTE работает по-другому. Но, оказалось, что это СТЕ даёт удобство написания и чтения запросов. Видимо, не более того.
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39750127
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

по тому пути он пускает. Ради интереса вытащи id_spr is not null наружу, ничего не изменится.

KreatorXXIКак уловить взаимосвязь между запросами в CTE?

Да там достаточно просто. Пока запрос внутри CTE не содержит order by, group by, агрегатных или оконных функций, ограничителей (first, skip, rows, fetch ...), то во внутренний запрос практически всегда проталкиваются предикаты. В твоём случае всё вообще можно заменить на последовательность join без CTE. C group by то же могут проталкиваться, но только по группируемым полям (не агрегатам). И это кстати помогает весьма оптимально выполнять такие запросы.
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39750132
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

мы же договорились, что не будем напрасно объяснять. Я свою часть договора выполняю
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39750149
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad,



KreatorXXI,

про union хитрые забыл. Может ещё что-то

На самом деле главная проблема оптимизатора с CTE в том, что для сложных случаев когда предикаты не проталкиваются внутрь
1. кардинальность выборки внутри CTE не оценивается
2. outer join не умеет выполняться как hash join (это вроде в 4.0 хотели сделать)

Ну и отдельная проблема это наличие left join, которые если возможно должны выполняться позже inner join.

KreatorXXIНо, оказалось, что это СТЕ даёт удобство написания и чтения запросов. Видимо, не более того.

не только, есть запросы которые без CTE/derived table не напишешь. И это не только рекурсивные запросы
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39750877
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисKreatorXXI,

по тому пути он пускает. Ради интереса вытащи id_spr is not null наружу, ничего не изменится.



мне непонятна реакция планировщика на "id_spr is not null". Этот кусок не имеет никакого смысла. Первичный ключ. Меня интересует почему без него всё плохо? Почти на 100 процентов уверен, что, если напишу ещё какую-нибудь глупость, планировщик среагирует на неё и будет всё OK.
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39750899
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI мне непонятна реакция планировщика на "id_spr is not null". Этот кусок не имеет никакого смысла.

а ты попробуй статистику пересчитай. Ещё можно попробовать на свежем снапшоте проверить (Дмитрий недавно что-то правил в оптимизаторе).
Если всё останется так же то в трекер. Ну или пока ДЕ не прояснит ситуацию.

Похоже c.id_spr is not null вырубил использование индекса по id_spr что в данном случае обернулось благом.

Но CTE тут скорее всего не причём. Думаю что запрос без CTE будет вести себя так же.

Ну и мне удобнее такой запрос читать вот так.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
with q (id_spr) as (
  select c.id_spr
  from sprav c
    join sprav d on d.id_spr = c.id_spar
    join sprav e on e.id_spr = d.id_spar
  where e.priz_spr=4 and e.s_name='PDCA'
)
select b.id_mdl
from q
  join statkit b on b.id_spr=q.id_spr



Виднее что ли кто к кому присоединён.
...
Рейтинг: 0 / 0
Работа планировщика при CTE.
    #39750985
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис
Похоже c.id_spr is not null вырубил использование индекса по id_spr что в данном случае обернулось благом.

Но CTE тут скорее всего не причём. Думаю что запрос без CTE будет вести себя так же.



Да, конечно. Без CTE поведение такое же. Теперь понятно, что планировщик работает также раз для CTE другого механизма нет. Значит будем ждать оптимизации работы оптимизатора. На последнем снапшоте проверить по горячим следам идея хорошая. Но вот насчёт того, что это баг, я что-то сомневаюсь. Поскольку нам очень много приходится писать запросов, сложных запросов, достаточно часто сталкиваемся с необъяснимым поведением планировщика. Поэтому CTE восприняли как благо. И написание, и чтение запросов лучше. И конечно рассчитывали в том числе и на изменения в работе планировщика. Но пока увы.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Работа планировщика при CTE.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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