и потом делаю where .как сначала выполнить where для одной таблички (например там есть where где is_calc = true) а потом только сделать join и сделать where по сравнению с двумя таблицами??
запрос примеерно такой
select
calculation.id,
calculation.participate_bet_sum,
calculation.level_id,
calculation.calculation_start,
calculation.calculation_end,
bets.bet_sum
from bets left outer join calculation on calculation.id = bets.id join participants on bets.id = participants.id
where bets.is_calculated = false and bets.calc_date between calculation.calculation_start and calculation.calculation_end and participants.is_participate = true
От перемены местами WHERE (для доступных столбцов) и INNER JOIN результат не меняется. Объясните детальнее, что вы хотите и чем вам не нравится очевидное решэние.
очень долго выполняется
https://t.me/pgsql/303899
calculation.id, bets.id, participants.id - проиндексированы?
Тогда попробуйте проиндексировать эти поля. В большинстве случаев наличие индексов на полях, по которым происходит JOIN, существенно повышает производительность выполнения запроса.
индекс participant_bets.id. есть. а воможно ли будет быстрее если отдельно получить выборку сначала таблицы по participant_bets.is_calculated = false participants.is_participate = true ?
нет. При наличии JOIN'ов с условиями и предложений WHERE движок БД сам принимает решение, в каком порядке проверять условия, чтобы запрос выполнялся быстрее (сам смотрит по индексам, по объемом выборок и т.д.)
Пробуйте, конечно. Впрочем, без индэкса на is_calculated это будет такжэ долго. А participants у вас и так выбирается и фильтруется за несущественное время. ЗЫ Индэкс на is_calculated, возможно, имеет смысл делать частичный (WHERE NOT is_calculated), ну или посмотреть на не-btree индэксы.
а подскажите конструкцию в рамках одного запроса, как сделать подвыборку сначала по is_calculated
В рамках одного запроса -- ну, можно попытаться через CTE materialized.
Но вообще -- в рамках одного запроса оно довольно малоосмысленно. В первую очередь из-за трудности понимания. Разбейте на несколько, если хотите проводить такие эксперименты.
а может ли быть медлительность проблемы из-за того что поля по которым делается JOIN текстовые, а не BigInt?
Зависит от количества записей в таблицах. Строки, конечно, сравниваются медленнее, чем числа, но чтобы это заметно проявилось, таблицы должны быть достаточно большими. Плюс вопрос с индексами (не помню, задавали ли уже)
понял. больше упор сделать на индексы
в одной из таблиц 34.00.000 записей с текстовой колонкой по которой происходит соединение
Да. Если мы делаем джоин двух таблиц без индексов, то SQL-серверу нужно "спарить" каждую запись из левой таблицы с каждой записью правой таблицы и проверить условие Join, после чего решить, оставлять эту запись, или нет. Т.е. объем работы MxN, где M и N количество записей в левой и правой таблице. Если же в правой таблице есть индекс по столбцу соединения, то для каждой записи левой таблицы SQL-сервер сразу "видит" список подходящих записей. Т.е. уже не приходится для каждой записи из левой таблицы пересматривать все записи правой таблицы.
А сколько записей в той таблице, с которой мы эту таблицу джойним? (общие рассуждения. Когда выполняется JOIN то серверу для каждой записи из левой таблицы нужно найти ответ на вопрос "есть ли в правой таблице записи с таким же значением поля соединения. Если индексов нет, единственным способом нахождения ответа на этот вопрос является просмотр всей таблицы. Индексы же - структуры данных, которые позволяют очень быстро получить ответ на вопрос, есть там такие значения, или нет. Например время полного просмотра таблицы на 1000 записей и 1 000 000 записей отличается в 1000 раз. А время поиска значений в индексах на 1000 и 1 000 000 значений отличается всего лишь в несколько раз. Поэтому индексы радикально ускоряют операции)
подскажите. а индексы сделать просто на колонку или с улосвием? create index idx_participant_bets_is_calculated on participant_bets (is_calculated); и create index idx_participant_bets_is_calculated on participant_bets (is_calculated) where (is_calculated = false);
Если в выборках нас интересуют только записи с is_calculated=false, то можно делать индекс с условием. Если же в других запросах нас интересуют записи с is_calculated=true, то, наверное, лучше индекс без условия. Хотя можно сделать и два индекса: один с true, второй с false. Зависит от того, сколько у нас тру и фолс в таблице, и в каких запросах кто нам из них нужен.
А оно вообще нормально делать индекс на колонку, в кот-й только 2 значения, или зависит от распределения?
для 2 значений индекс не нужен
ну в оракеле бывает вроде такое
Индекс с условием для boolean может быть нужен для кейса когда одного вида значениq значительно (на порядок, а лучше на 2-3) меньше чем другого. А так да, при примерно равном числе он просто использоваться не будет
да уже понял, подумал про две строки
Обсуждают сегодня