![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вложенные запросы
Piter © (2004-08-21 00:02:00)Вот читаю тут литературу. Пишут, что вложенные подзапросы оформляются так:
SELECT *
FROM Orders
WHERE snum = (
SELECT snum
FROM Salespeople
WHERE city = 'Москва'
)
При этом если подзапрос возвращает несколько значений, то писать вроде как нужно так:
SELECT *
FROM Orders
WHERE snum IN (
SELECT snum
FROM Salespeople
WHERE city = 'Москва'
)
То есть, заменять '=' на 'IN'. Но когда я так делаю в программе - то сервер начинает жутко тормозить, в конце концов все выполняет правильно, но делает это больше минуты! (на базе в 7Mb).
Если же писать все таки '=', то не смотря на то, что подзапрос возвращает несколько строк - все проходит опять же на ура, но ГОРАЗДО быстрее (меньше секунды)...
Ничего не понимаю! Что же происходит?
P.S. Эксперименты проводил на различных Firebird серверах
Sandman25 (2004-08-21 14:06:00) [21]Если возвращается несколько одинаковых записей, то для IB стоит писать
= (select distinct ...)
Nikolay M. (2004-08-21 13:46:00) [22]А если так? Должно быть быстро
SELECT *
FROM Orders o
WHERE EXISTS (SELECT 1
FROM Salespeople s
WHERE s.city = 'Москва' AND s.snum = o.snum)
Piter (2004-08-21 13:40:00) [23]Моя не понимать... а нафига такое сделано? Кто такие подзапросы делает??! На моей малюсенькой базе в 7 Mb он выполняется минуту!!! При этом ничего не возвращая.
То есть, если отдельно сделать внутренний запрос, то он ничего не вернет! При этом он вызывается для каждой записи внешнего запроса! ГЛУПО!
И что, собственно, теперь делать?
Мне в общем, нужна реализация случая, когда ставится '=', но чтобы он работал в случаях, когда внутренний запрос возвращает несколько записей!
Или я уже подумываю, чтобы вручную сделать внутренний подзапрос и сохранить все выданные snum, а потом сделать n-ое количество внешних запросов с этими полученными snum...
Но как-то опять же глупо получается...
P.S. А когда этот IN применяется то? Ведь если он выполняется для КАЖДОЙ записи таблицы из внешнего запроса? На кой он нужен? Тормознее его, наверное, ничего нету...
P.N.P. (2004-08-21 12:44:00) [24]именно так.
Piter (2004-08-21 12:40:00) [25]Так, правильно я понимаю, что для конструкции с '=' будет сначала выполнен внутренний запрос, а потом на основе его данных внешний? А если поставить IN, то сначала будет выполнен внешний запрос, каждый раз вызывая внутренний?
Или как?
P.N.P. (2004-08-21 01:57:00) [26]http://www.krista.ru/ib/subq-opt.html#SECTION00033000000000000000
Piter (2004-08-21 00:55:00) [27]У меня есть мысль, что поведение Firebird и MSSQL в этом деле различаются...
В общем, неплохо, чтобы кто-нибудь знающий пояснил...
Piter (2004-08-21 00:54:00) [28]P.N.P. © (21.08.04 0:34) [1]
в том то и дело, что нет.
Если писать IN, то сервер обрабатывает запрос около минуты!!! Это при том, что внутрений запрос сам по себе отрабатывает меньше секунды! И еще не возвращает ничего (условия не выполнены). И все равно сложный запрос работает минуту! Вот что странно...
А при использовании '=' - все ок и очень быстро. Я целый день с этим промучился...
P.N.P. (2004-08-21 00:34:00) [29]Что-то Вы путаете...
Если писать '=' и подзапрос возвращает несколько строк, то
сервер будет ругаться
multiple rows in singleton select