Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

EXISTS или IN


novichek ©   (2011-03-22 11:40:00) 

подскажите пожалуйста, что быстрее или правильнее использовать?

select a.naimen from a
where
 exists (select b.kod from b where b.kod = a.kod)

или

select a.naimen from a
where a.kod in
        (select b.kod from b where b.kod = a.kod)

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

так же подскажите пожалуйста, имеет ли смысл вынести выбор в хранимую процедуру, которой будет передаваться как строка условие отбора 'where ...'
пока кажется что смысла нет, так как план тут и непонятно как строиться будет если условие само приходит в процессе работы..


OW   (2011-03-23 08:30:00) [1]


> Насчет [10]. Во-первых, хранимка тут нафик не нужна (все
> равно кусок SQL-кода генерится на клиенте).


вот примерно так, но не совсем.

Клиент анализирует, что допустим, задали фильтр по услоовию А, и только по А. Тогда он вызывает хранимку, заточенную только под А.

Б - под Б

говорю же, чаще всего такие (2-3) и определяют 90% запросов.
А для 10%
> SQL-код генерится на клиенте


Loginov Dmitry   (2011-03-22 21:55:00) [2]


> 1) я не использую join


Почему? Из каких соображений?
Глядя на [6] представляется, что правильней было бы [7].
При этом никто и ничего не мешает текст запроса генерировать динамически, и без каких-либо параметров.

Насчет [10]. Во-первых, хранимка тут нафик не нужна (все равно кусок SQL-кода генерится на клиенте). Во-вторых, если все же есть непреодолимое желание вывернуться на хранимках, то используй EXECUTE STATEMENT (см. Firebird 2.0.1 Release Notes на www.firebirdsql.org)


Игорь Шевченко   (2011-03-22 16:30:00) [3]

спустя 12 постов определилась база данных.
тебе с твоим вопросом на http://ibase.ru


novichek   (2011-03-22 16:26:00) [4]

я ненашел такого описания для FireBird


Игорь Шевченко   (2011-03-22 15:31:00) [5]


> что быстрее или правильнее использовать?


мозг для чтения документации по своей СУБД


OW   (2011-03-22 14:28:00) [6]


> до 5 таблиц, в которых ещё может с пяток полей

наверное, тогда нет смысла

можно, конечно попробовать разбить на несколько процедур, с наиболее частыми условиями
(выяснить по тестам/логам, т.к. у меня, например, из всех наворотов (не спорю, глючных, местами), используют только один-два критерия поиска. Думаю сделать три процедуры - две этих, плюс 1 динамическая, для всех кому интересно сложные фильтры делать)


novichek   (2011-03-22 14:12:00) [7]

create procedure test (myFilter varchar)
return
returns (_naimen varchar(30))
as
begin

 for select a.name
     from a
     where :myFilter
     into :_naimen
 do
     suspend;

end

а смысл тогда использования хранимой процедуры какой будет?

я понимаю когда условие одно, только параметры передавай. сервер оптимизирует или что там сделает ..
а тут выходит что условие пользователь сам строит. может использовать до 5 таблиц, в которых ещё может с пяток полей использоваться для отбора.

наверное смысла нет.


b z   (2011-03-22 13:33:00) [8]

Так передавайте не одним параметром.


novichek   (2011-03-22 13:29:00) [9]

да, вероятно я неверно сформулировал условие..

1) я не использую join
2) пользователь сам выбирает параметры отбора, поэтому условие в where конечно всегда разное иначе я бы использовал хранимую процедуру однозначно.
а если условие разное, то как понял смысла хранимой процедуры, в которую передавался бы один строковый параметр (весь where) нету.


OW   (2011-03-22 13:02:00) [10]


> Anatoly Podgoretsky ©   (22.03.11 12:19) [5]


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



> select a.naimen from a
> where
>   (exists (select b.kod from b where (b.kod = a.kod) and
> (b.tip=1) and (..) ) ) and

select
a.naimen
from
a
join b on b.kod = a.kod
join с on c.kod = a.kod
join d on d.kod = a.kod
where
1 = 1
and b.tip = :P1
and c.tip = :P2
and d.tip = :P3


novichek   (2011-03-22 12:38:00) [11]

к сожалению я пока только пишу код и ничего проверить\измерить не могу )

запрос примерно такой:

select a.naimen from a
where
  (exists (select b.kod from b where (b.kod = a.kod) and (b.tip=1) and (..) ) ) and
  (exists (select c.kod from c where (c.kod = a.kod) and (c.opt=1) and (..) ) ) and
  (exists (select d.kod from d where (d.kod = a.kod) and (d.xxx=1) and (..) ) )

что - то наподобии такого..
фильтр отбора устанавливает пользователь..

параметрами не сделать, так как условия выбора динамические, прийдется переоткрывать изменяя полностью select SQL.
хранимую процедуру то же смысла нет делать как понял.

плохо что приходится заново открывать таблицы b,c,d так как они привязаны к мастер таблице 'а'
по идее если перевести на параметры или хранимую процедуру то переоткрывать не пришлось бы, т.к. тут ещё вдобавок клиент - сервер

ну и лучше использовать в данном случаи exists чем IN


Anatoly Podgoretsky   (2011-03-22 12:19:00) [12]

> OW  (22.03.2011 11:45:02)  [2]

А где тут применим параметр.


Anatoly Podgoretsky   (2011-03-22 12:17:00) [13]

> novichek  (22.03.2011 11:40:00)  [0]

Что показывает план исполнения, что показывают измерения?


novichek   (2011-03-22 11:56:00) [14]

спасибо, понял!

насчет параметра сейчас подумаю,
просто where будет если пользователь установит фильтр
иначе что туда писать? истину? myparam:= True

where :myparam


OW   (2011-03-22 11:45:00) [15]


> имеет ли смысл вынести выбор в хранимую процедуру, которой
> будет передаваться как строка условие отбора 'where ...'

имхо, нет
use parametr.


OW   (2011-03-22 11:43:00) [16]

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

select
 a.naimen
from
 a
 join b on b.kod = a.kod


Наверх

Титульная страница Поиск, карта сайта Написать письмо