Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей? / 14 сообщений из 14, страница 1 из 1
13.10.2014, 01:06:22
    #38774638
ElenaTomsk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
Подскажите, пожалуйста!

Вот если я сделала так:


select * from tbl_table1 t1
JOIN tbl_table2 t2 on t1.Id=t2.id

и теперь надо соединится с другой таблицей, но по условию. Условие у меня будет в переменной такой - If_valueexists и если она не null, то надо присодинять таблицу.

Можно сделать это двумя запросами:

if not If_valueexists is null
begin
select * from tbl_table1 t1
JOIN tbl_table2 t2 on t1.Id=t2.id
end
else

begin
select * from tbl_table1 t1
JOIN tbl_table2 t2 on t1.Id=t2.id
JOIN tbl_table3 t3 on t2.Id_t = t3.id_t
end

А еще можно
select * from tbl_table1 t1
JOIN tbl_table2 t2 on t1.Id=t2.id
LEFT JOIN tbl_table3 t3 on t2.Id_t = t3.id_t and (If_valueexists is null or t3.id_t is not null)
понятно, наверное? я могла сейчас ошибиться, но смысл в зависимости от переменной превратить left join в inner, убрав пустые строки.

Что оптимизатор поймет лучше или ему без разницы?
...
Рейтинг: 0 / 0
13.10.2014, 06:36:11
    #38774684
tanglir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
ElenaTomskЧто оптимизатор поймет лучшепервое
...
Рейтинг: 0 / 0
13.10.2014, 09:07:24
    #38774730
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
Очень странное условие
Код: sql
1.
LEFT JOIN tbl_table3 t3 on t2.Id_t = t3.id_t and (If_valueexists is null or t3.id_t is not null)



Если t3.id_t is null , условие трансформируется в
Код: sql
1.
LEFT JOIN tbl_table3 t3 on t2.Id_t = null and (If_valueexists is null or false)


Итог - false, и записи третьей таблицы не присоединяются вне зависимости от If_valueexists.

Если t3.id_t is not null , условие трансформируется в
Код: sql
1.
LEFT JOIN tbl_table3 t3 on t2.Id_t = t3.id_t and (If_valueexists is null or true)


и записи третьей таблицы присоединяются вне зависимости от If_valueexists.
...
Рейтинг: 0 / 0
13.10.2014, 11:53:34
    #38774898
ElenaTomsk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
Akina,

извините, я могла ошибиться там в условии, конечно. Вопрос не в этом, напишу правильно потом. Вопрос в том, что лучше для оптимизатора.
...
Рейтинг: 0 / 0
13.10.2014, 12:27:24
    #38774952
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
На ошибочный вопрос можно получить ошибочный ответ.

Сначала напишите правильно. Потом будем думать, что решит оптимизатор, и как сделать, так, чтобы он решил правильно.

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

С другой стороны, в зависимости от условия изменяется структура результата - а это свидетельствует о серьёзных проблемах архитектуры. Так что не об эффективности запроса должна голова болеть...
...
Рейтинг: 0 / 0
13.10.2014, 13:05:43
    #38775033
tanglir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
AkinaОчень странное условиеНу какая задача , такое и условие :)
...
Рейтинг: 0 / 0
13.10.2014, 14:00:40
    #38775110
Users
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
Akina,

Ваша правда, я пока неочень опытная. :(

Но мне кажется, что тут я не ошибаюсь. Поправите? Например, группа студентов. У них есть какой-нибудь необязательный признак. Например, второе гражданство. Страна с ним лежит в отдельной таблице
На форме выбрка, получить всех студентов, если в выборке не указано второе гражданство. Другой вариант, если второе гражданство указано.
...
Рейтинг: 0 / 0
13.10.2014, 15:39:32
    #38775275
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
UsersНапример, группа студентов. У них есть какой-нибудь необязательный признак. Например, второе гражданство. Страна с ним лежит в отдельной таблице
На форме выбрка, получить всех студентов, если в выборке не указано второе гражданство. Другой вариант, если второе гражданство указано.
Минутку. Не понимаю, как ЭТО влияет на конечный РЕЗУЛЬТАТ.
В любом случае гражданство на форму ВЫВОДИТСЯ. Следовательно, в любом случае оно в выходном наборе данных от сервера ПРИСУТСТВУЕТ. Следовательно, таблица гражданств в любом случае ПРИВЯЗЫВАЕТСЯ, то есть в источнике данных (запросе) ПРИСУТСТВУЕТ.

Другое дело, будет ли оно использоваться при отборе данных или нет. Это уже определяется параметром, который передаст движку форма ввода фильтра.

Посему - запрос всегда один и тот же.
...
Рейтинг: 0 / 0
13.10.2014, 16:29:17
    #38775370
javajdbc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
AkinaUsersНапример, группа студентов. У них есть какой-нибудь необязательный признак. Например, второе гражданство. Страна с ним лежит в отдельной таблице
На форме выбрка, получить всех студентов, если в выборке не указано второе гражданство. Другой вариант, если второе гражданство указано.
Минутку. Не понимаю, как ЭТО влияет на конечный РЕЗУЛЬТАТ.
В любом случае гражданство на форму ВЫВОДИТСЯ. Следовательно, в любом случае оно в выходном наборе данных от сервера ПРИСУТСТВУЕТ. Следовательно, таблица гражданств в любом случае ПРИВЯЗЫВАЕТСЯ, то есть в источнике данных (запросе) ПРИСУТСТВУЕТ.

Другое дело, будет ли оно использоваться при отборе данных или нет. Это уже определяется параметром, который передаст движку форма ввода фильтра.

Посему - запрос всегда один и тот же.

есть прoмежуточный вариант для несложный случаев:
запрос один но связка не всегда задействована, типа:

Код: sql
1.
2.
3.
4.
5.
6.
select
  (case
    when :filter77 is null then '-'
    else (select abc from bcd where id = :filter77)
  end)  cde
from dual
...
Рейтинг: 0 / 0
13.10.2014, 16:34:28
    #38775374
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
Почему не просто
Код: sql
1.
WHERE (country = :filter) or (:filter is null)


?
...
Рейтинг: 0 / 0
13.10.2014, 18:19:59
    #38775516
javajdbc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
AkinaПочему не просто
Код: sql
1.
WHERE (country = :filter) or (:filter is null)


?

любопытно (но лень проверять)

Скорее всего
WHERE (country = :filter) or (:filter is null)
сначала всегда сделает джоин а потом проверит на НУЛЛ если не найдет (country = :filter)

а вот
WHERE (:filter is null) or (country = :filter)
возможно не будет делать джоин если (:filter is null)

И вообше: порядок выполнения операторов одного уровня
слева направо в WHERE секции определен или нет?
Кто нибудь знает?
...
Рейтинг: 0 / 0
13.10.2014, 18:31:55
    #38775524
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
ElenaTomskПодскажите, пожалуйста!

Вот если я сделала так:


select * from tbl_table1 t1
JOIN tbl_table2 t2 on t1.Id=t2.id

и теперь надо соединится с другой таблицей, но по условию. Условие у меня будет в переменной такой - If_valueexists и если она не null, то надо присодинять таблицу.

Можно сделать это двумя запросами:

if not If_valueexists is null
begin
select * from tbl_table1 t1
JOIN tbl_table2 t2 on t1.Id=t2.id
end
else

begin
select * from tbl_table1 t1
JOIN tbl_table2 t2 on t1.Id=t2.id
JOIN tbl_table3 t3 on t2.Id_t = t3.id_t
end

А еще можно
select * from tbl_table1 t1
JOIN tbl_table2 t2 on t1.Id=t2.id
LEFT JOIN tbl_table3 t3 on t2.Id_t = t3.id_t and (If_valueexists is null or t3.id_t is not null)
понятно, наверное? я могла сейчас ошибиться, но смысл в зависимости от переменной превратить left join в inner, убрав пустые строки.

Что оптимизатор поймет лучше или ему без разницы?
иногда будет без разницы, но в принципе лучше всегда делать два запроса
...
Рейтинг: 0 / 0
13.10.2014, 18:46:07
    #38775534
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
javajdbcAkinaПочему не просто
Код: sql
1.
WHERE (country = :filter) or (:filter is null)


?

любопытно (но лень проверять)

Скорее всего
WHERE (country = :filter) or (:filter is null)
сначала всегда сделает джоин а потом проверит на НУЛЛ если не найдет (country = :filter)

а вот
WHERE (:filter is null) or (country = :filter)
возможно не будет делать джоин если (:filter is null)

И вообше: порядок выполнения операторов одного уровня
слева направо в WHERE секции определен или нет?
Кто нибудь знает?

я знаю. не определен.
порядок выполнения чего-либо в sql вообще не определен .

в процедурном языке расширении наоборот строго определен.
...
Рейтинг: 0 / 0
13.10.2014, 18:53:35
    #38775541
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей?
javajdbc, constant evaluation, емнип, делается до всех остальных телодвижений.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / неизвестный заранее джойн: два разных запроса или один с переменной: чтобыстрей? / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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