Size: a a a

pgsql – PostgreSQL

2021 June 12

R

Radist in pgsql – PostgreSQL
А что он должен делать с этими "предложениями"? Он и так рассматривает все разумные варианты джойнов. Единственный вариант, когда это было бы полезно - когда в запросе таблиц больше чем geqo_threshold (возможно, неправильно название параметра привёл), т.е., когда включается генетический оптимизатор.
источник

S

Slava in pgsql – PostgreSQL
Всем привет
Подскажите, пожалуйста, куда посмотреть:
есть запрос к постгресу, который возвращает набор интервалов — время корпоративов, исключая время в отпуске ( получаю подзапросом ).
Я пока не могу понять, как исключить интервалы из основного запроса, которые входят в результаты подзапроса.
Выглядит вот так:
SELECT corporate_party.start_at - corporate_party.end_at as corp
FROM "user_profile"
        INNER JOIN "user_profile_corporate_party"
                   ON ("user_profile"."id" = "user_profile_corporate_party"."user_profile_id")
        INNER JOIN "corporate_party" ON ("user_profile_corporate_party"."corporate_party_id" = "corporate_party"."id")
WHERE (("user_profile.id" = $1) AND ("corporate_party.start_at" >= $2) AND ("corporate_party.end_at" <= $3) AND
      ("corp" NOT IN ((SELECT end_at - start_at
                       FROM "vacation"
                       WHERE (("end_at" <= $4) AND ("start_at" >= $5) AND ("user_profile_id" = $6))))))
основная сложность для меня в самом конце — вот тут
("corp" NOT IN ((SELECT end_at - start_at
                       FROM "vacation"
                       WHERE (("end_at" <= $4) AND ("start_at" >= $5) AND ("user_profile_id" = $6))))))
corp — это интервал, и подзапрос — тоже возвращает набор интервалов
Ну, или возможно я вообще не правильно подумал о решении этой задачи и есть какой - то другой способ ?)
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
Да, я писал про этот вариант.

А другие хинты, которые не на основе costs, я вообще не понимаю, потому что можно легко придумать пример, когда они дадут неоптимальный план.
источник

R

Radist in pgsql – PostgreSQL
Интересно, а порядок следования таблиц в запросе не влияет на то, в какой последовательности geqo будет перебирать варианты? Если влияет, то выходит, что хинты и не нужны, достаточно перестановками добиться того, чтобы генетический алгоритм находил быстрый план.
Хотя, конечно, это трудоёмкий метод.
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
Хм... Получается, что хинты уже есть. Спасибо)
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
А я, например, не могу понять по описанию, в чём суть задачи (да и тип данных всех этих start_at неизвестен).
И да, запрос написан странно (трудно читать) — слишком много quoting, как будто это какой-то генератор / ORM, но наличие отдельных неквалифицированных полей, вроде ("corporate_partystart_at" >= $2) как бы намекает, что нет...
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
Ещё чуть-чуть подумал и... всё-таки нет, не достаточно.

Возможно будет хотеться соединять попарно разные таблицы, а потом их результаты соединять (в предположении, что результаты первых соединении содержат мало данных).
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
Я вот, например, сходу даже не помню (потому что таких запросов — единицы, особенно если поднять from_collapse_limit и join_collapse_limit), но необязательно перестановками удастся вообще чего-то добиться (потому что GEQO не перебирает варианты последовательно, поэтому тут как повезёт).
источник

R

Radist in pgsql – PostgreSQL
Если знаете, что какие-то две таблицы дадут немного данных, можете их спрятать под CTE.
Собственно, у меня был опыт оптимизации запросов, написанных по беспощадной аналитике (выводим кучу полей с расшифровками, плюс довольно сложные правила доступа к данным и динамические условия отбора + сортировки), но почти всегда была возможность переписать запрос так, чтобы не попадать на geqo. За одним исключением, в котором почему-то geqo работал лучше (но, вроде, после решения проблем с условиями, селективность которых не получалось нормально оценить, его тоже упростили).
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
Да, в моей жизни тоже запросы на ~ 10 join-ов было не так много.
И кажется то, как строил PG запрос, всех удовлетворяло.

Вообще не понимаю тогда чуваков, которые хотят хинты. Ну вот для хитрых запросов, разве что, на которые не удается статистику сделать правильной.
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
> Если знаете, что какие-то две таблицы дадут немного данных, можете их спрятать под CTE.

Уже (в последних версиях) бесполезно. ;)

> почти всегда была возможность переписать запрос так, чтобы не попадать на geqo

При стандартных настройках на GEQO вообще невозможно "попасть", если правильно помню (в отличие от *_collapse_limit).
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
Ну так таких запросов хватает — все эти "Optimizer failure". И даже тут их разбирали немало. ;)
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
А разве при превышении collapse_limit не используется geqo?
источник

R

Radist in pgsql – PostgreSQL
> Уже (в последних версиях) бесполезно. ;)
В смысле бесполезно? Не помню, чтобы отменяли материализованные CTE.
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
В последних версиях можно добавить слово materialize возле CTE.
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
Отменили в v12.
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
Кстати, это тоже hint.
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
Нет, это не hint. Если бы удалось сохранить такое же поведение запросов (в смысле сохранения результатов), как до v12, в абсолютно всех случаях, никакого MATERIALIZED почти наверняка не было бы.
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
Насколько я помню, наоборот.
источник

R

Radist in pgsql – PostgreSQL
Среди оракловых админов популярно. И тут две причины: во-первых, так проще быстро потушить пожар, во-вторых, при переходе с 11 на 12 там довольно сильно доработали планировщик, что вернуть нормальное поведение не получается даже включением настроек от 11й версии, при чём в достаточно типичном случае подзапроса выбирающего макс. дату из историчной таблицы, строится кривой план (возможно, это намёк на то, что не стоит так проектировать БД, чтобы приходилось постоянно такие подзапросы писать, но в oracle нет exclusion constraint, чтобы удобно контролировать целостность историчной таблицы с указанием даты окончания в каждой записи).
источник