172 похожих чатов

Подскажите плиз. имею огромную таблицу. сотни миллионов строк. я делаю join таблиц.

и потом делаю 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

27 ответов

28 просмотров

От перемены местами WHERE (для доступных столбцов) и INNER JOIN результат не меняется. Объясните детальнее, что вы хотите и чем вам не нравится очевидное решэние.

calculation.id, bets.id, participants.id - проиндексированы?

Илья Я Я
нет

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

Илья Я-Я Автор вопроса
Юра
Тогда попробуйте проиндексировать эти поля. В боль...

индекс participant_bets.id. есть. а воможно ли будет быстрее если отдельно получить выборку сначала таблицы по participant_bets.is_calculated = false participants.is_participate = true ?

Илья Я Я
индекс participant_bets.id. есть. а воможно ли бу...

нет. При наличии JOIN'ов с условиями и предложений WHERE движок БД сам принимает решение, в каком порядке проверять условия, чтобы запрос выполнялся быстрее (сам смотрит по индексам, по объемом выборок и т.д.)

Илья Я Я
индекс participant_bets.id. есть. а воможно ли бу...

Пробуйте, конечно. Впрочем, без индэкса на is_calculated это будет такжэ долго. А participants у вас и так выбирается и фильтруется за несущественное время. ЗЫ Индэкс на is_calculated, возможно, имеет смысл делать частичный (WHERE NOT is_calculated), ну или посмотреть на не-btree индэксы.

Илья Я-Я Автор вопроса
Ilya Anfimov
Пробуйте, конечно. Впрочем, без индэкса на is_calc...

а подскажите конструкцию в рамках одного запроса, как сделать подвыборку сначала по is_calculated

Илья Я Я
а подскажите конструкцию в рамках одного запроса,...

В рамках одного запроса -- ну, можно попытаться через CTE materialized.

Илья Я Я
а подскажите конструкцию в рамках одного запроса,...

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

Илья Я-Я Автор вопроса
Ilya Anfimov
В рамках одного запроса -- ну, можно попытаться че...

а может ли быть медлительность проблемы из-за того что поля по которым делается JOIN текстовые, а не BigInt?

Илья Я Я
а может ли быть медлительность проблемы из-за того...

Зависит от количества записей в таблицах. Строки, конечно, сравниваются медленнее, чем числа, но чтобы это заметно проявилось, таблицы должны быть достаточно большими. Плюс вопрос с индексами (не помню, задавали ли уже)

Илья Я-Я Автор вопроса
Юра
Зависит от количества записей в таблицах. Строки, ...

понял. больше упор сделать на индексы

Илья Я-Я Автор вопроса
Юра
Зависит от количества записей в таблицах. Строки, ...

в одной из таблиц 34.00.000 записей с текстовой колонкой по которой происходит соединение

Илья Я Я
понял. больше упор сделать на индексы

Да. Если мы делаем джоин двух таблиц без индексов, то SQL-серверу нужно "спарить" каждую запись из левой таблицы с каждой записью правой таблицы и проверить условие Join, после чего решить, оставлять эту запись, или нет. Т.е. объем работы MxN, где M и N количество записей в левой и правой таблице. Если же в правой таблице есть индекс по столбцу соединения, то для каждой записи левой таблицы SQL-сервер сразу "видит" список подходящих записей. Т.е. уже не приходится для каждой записи из левой таблицы пересматривать все записи правой таблицы.

Илья Я Я
в одной из таблиц 34.00.000 записей с текстовой ко...

А сколько записей в той таблице, с которой мы эту таблицу джойним? (общие рассуждения. Когда выполняется 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. Зависит от того, сколько у нас тру и фолс в таблице, и в каких запросах кто нам из них нужен.

Юра
Если в выборках нас интересуют только записи с is_...

А оно вообще нормально делать индекс на колонку, в кот-й только 2 значения, или зависит от распределения?

central hardware
для 2 значений индекс не нужен

ну в оракеле бывает вроде такое

central hardware
для 2 значений индекс не нужен

Индекс с условием для boolean может быть нужен для кейса когда одного вида значениq значительно (на порядок, а лучше на 2-3) меньше чем другого. А так да, при примерно равном числе он просто использоваться не будет

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Ребят в СИ можно реализовать ООП?
Николай
33
Подскажите пожалуйста, как в CustomDrawCell(Sender: TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean); получить наз...
A Z
7
Карта сайта