join по большим таблицам, после этого идет where.. если переписать запрос (возможно с подзапросом), максимально сократить выборку, и делать join уже по этой малой выборке - запросы ускоряются в разы.. как правильно называется такое явление? как бороться системно?
https://t.me/pgsql/303899
Вы бы пример показали (потому что, на первый взгляд, такое явление называется "мифотворчество", серьёзно).
SELECT o.1, s.2 FROM order o LEFT JOIN status s ON s.id=o.sid LEFT JOIN ... LEFT JOIN ... WHERE o.field = 1 AND ... SELECT o.1 s.2 FROM ( SELECT * from order WHERE field = 1 ) o LEFT JOIN status s ON s.id=o.sid WHERE ... если таблица order большая - сначала идет долгое объединение всех таблиц (через диск, медленно), потом по всему объему делается WHERE есть вариант WHERE order_id IN (select id from ... одна из join table) сталкиваюсь с таким регулярно, как на postgres, так и на mysql
> сталкиваюсь с таким регулярно, В PostgreSQL — нет, не сталкиваетесь (в норме). Для того, чтобы что-то такое происходило, нужны особые условия, которые в принципе приводят к тому, что такое "переписывание" является некорректным ([потенциальные] результаты запросов меняются, то есть). > так и на mysql MySQL — это совсем другой вопрос, не в этот чат. Что касается этого чата — покажите что-то конкретное уже. ;)
я же показал идею, таблица order - 80+ гб, если прогеры пишут все в кучу - select ... join a, b,c where - эти все таблицы сначала объединяются, потом идет where, если перенести where в подзапрос, и по маленькой выборке делать join других таблиц - результаты в разы лучше.. с минут до миллисекунд я сокращал волшебные запросы программистов
Я пытался [вежливо] донести до Вас, что сама эта идея — феерическая чушь, всего лишь (что касается PostgreSQL). > с минут до миллисекунд я сокращал волшебные запросы программистов См. выше про то, почему так могло быть. Если не хотите показывать ничего конкретного, то правильное название этой "идеи" (почти во всех случаях) я Вам уже написал.
конкретные запросы с прод системы показать не могу к сожалению, думал идея будет понятна
Идея понятна, только к реальности отношение она имеет в исключительных случаях.
к сожалению нет, я уже 4+ таких ситуации разрешил, 3 на pg.. программисты делают "чтобы работало", плохо просчитывают рост.. со временем таблицы растут
К сожалению да, и Вы почти наверняка сделали неправильные выводы из этих ситуаций (а то и "сломали" запросы). :(
это прод система, и ситуации заключались в том, что сервер вставал колом, из-за объединения огромных таблиц (одна из них - 80+гб) на диске.. всё успешно разрешилось.. сталкивался с таким же на mysql, поэтому и обратился тут к знатокам, думаю это общая болезнь архитектурная/запросов
Да сколько можно-то, в конце концов! Что касается именно PostgreSQL: Это. Феерическая. Чушь. Вам это ещё несколько раз повторить?! Если хотите разобраться, почему в тех случаях что-то менялось (а вариантов хватает, я уже упоминал некоторые выше) — нужна хоть какая-то конкретика. Если Вы хотите запомнить какой-то бред вроде "это общая болезнь архитектурная" — боюсь, Вам тут с этим не помогут. ;)
ваши великолепные эмоции точно не помогут подобрать этому явлению правильное название )
Мы все не видим явления кроме ваш слов
Уже помогли. Вы вообще разбираетесь, как работают современные планировщики запросов, хотя бы минимально? Если нет — то, что Вы пишете, в общем случае противоречит даже базовым принципам их функционирования, просто для информации.
на каждый хитрый планировщик, как показывает практика, найдется ленивый изобретательный эмо-программист
жаль, я старался.. в любом случае спасибо!
ну, справедливости ради, есть исключение: если соединений столько, что включился geqo, тогда... :)
В моём сообщении жирным чёрным по белому было написано: > в типичных случаях (когда осуществляется полный перебор всех возможных планов) между прочим. ;)
Да, кстати — при default настройках geqo на практике не включается никогда (нет, если кому-то удастся написать запрос с 60 (или более?) JOINs, то...).
geqo_threshold вроде по дефолту "всего" 12. Много, но не безумно много.
И это не имеет значения, потому что from_collapse_limit и join_collapse_limit по умолчанию меньше. Т.е. в норме он в самом деле никогда не включается (и я даже не уверен насчёт "более 60" — это надо в свои записи подсмотреть...).
т.е. geqo_threshold применяется уже после того как "поколлапсили" в соответствии с *_collapse_limit? так-то они оба по дефолту равны 8. Я это понимал так, что если таблиц больше 12, то включаем geqo, а иначе начинаем что-то там коллапсировать...
Да, после. Я могу подробности потом поискать, если интересует...
Очень интересная информация, в доке такого не нашёл, а жаль
в запросе с прода 10 join, но их столько же и остается, однако запрос с саб-селектом выполняется 0.38сек, без саб-селекта 1мин30сек+, я вижу проблему именно в порядке select ... join ... where
замените названия таблиц и/или полей, если там уж что-то шибко секретное, и покажите запросы и их планы до и после. а так...
Без норм запроса или норм примера который 1 в 1 с вашим запросом тяжело что то сказать. Не можете ваш код с прода - ок. Накидайте свой пример. Выше правильно сказали. Это либо настройки дурные Либо в join чето теряется или вы подзапросом что то теряете...
Либо где-то в join некорректное условие, например идет условие на неравнозначные поля ( если речь идет про констрэинт )
А подзапросом вы условно правильно отбираете часть данных
Оно там не можэт возвращаться в join_collapse_limit потому, что это ужэ subquery и они считаются по from_collapse_limit?
Вот, наконец-то какая-то конкретика! Вот это уже может быть причиной построения других планов (но Ваш вывод от этого правильным не становится, между прочим). Но вместо того, чтобы переписывать, Вы просто могли бы увеличить from_collapse_limit и join_collapse_limit до 12 (смело), и забыть об этой проблеме. И да, если есть ещё более сложные запросы — эти параметры (с соответствующим увеличением geqo_threshold) можно на современном железе запросто ставить и 14, а если хочется попробовать GEQO — то его можно оставить default, а сами параметры смело поднять до 20.
Потому что collapse limits "режут" запрос на planning subproblems такого размера, а geqo включается тогда, когда размер любой из них превышает geqo_threshold, вкратце.
а почему внесение условия в подзапрос может повлиять на порядок соединений?
(Ради справедливости) А я вот нашёл, причём даже дважды: В описании from_collapse_limit и в описании join_collapse_limit: "Setting this value to geqo_threshold or more may trigger use of the GEQO planner, resulting in non-optimal plans." Чёрным по белому, нет? ;)
Потому что: from_collapse_limit (integer) The planner will merge sub-queries into upper queries if the resulting FROM list would have no more than this many items.
Я не про геко, я про то, что оно могло сильно по-другому попезаться из-за переноса кое-чего с join_* во from_* .
Так он не переносил, вроде бы? Вот https://t.me/pgsql/489459 и вот https://t.me/pgsql/489456 — такое было описание...
По-моему как раз перенёс. Из просто JOIN в sub-select. Впрочем, да, эти все гадания, конечно, непродуктивны абсолютно. Человек, неумеющий пользоваться инжэнерным инструментарием — всё равно будет страдать.
Обсуждают сегодня