Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.09.13;
Скачать: CL | DM;

Вниз

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

 
pavel_guzhanov ©   (2008-11-19 10:15) [0]

Один запрос определяет ID, но запрос достаточно тормозной. В цикле в каждую итерацию этот запрос выполняется снова и снова. Цикл работает очень долго. У запроса есть один параметр, каждую итерацию цикла значение этого параметра меняется.

Хочется сделать так: Запрос выбирает все ID, вне зависимости от параметра, но удовлетворяющие остальным условиям. Нужно проверить результат другого запроса, вернул ли он ID, выбранные первым запросом. Если в цикле просматривать каждую запись из возвращенных вторым запросом, то это тоже будет долго. Можно ли как-то проверить, входит ли значение в набор данных, не прибегая к циклу?

Тоесть хочется примерно такого:
if query1.FieldByName("ID").AsInteger in Query2.FieldByName("ID").asInteger then...

Query1 возвращает одно значение, query2 - несколько значений.

PS Понимаю, что написал сумбурно, но как-то затрудняюсь более конкретно сформулировать....


 
stone   (2008-11-19 10:21) [1]

Locate ? Lookup ?


 
Sergey13 ©   (2008-11-19 10:22) [2]

IN


 
Виталий Панасенко   (2008-11-19 10:24) [3]

Сделай с точностью наоборот: во второй запрос выбери ВСЕ(и сделай FetchAll). А далее: Locate.. в памяти будет работать гораздо быстрее, чем каждый раз дергать сервер.Я как-то делал подобное для MS SQl.. то же связь мастер-деталь(со своими заморочками-вычислениями).в первом варианте каждый раз "дергал" сервер.. работало несколько часов.. при чем долгих.. потом переделал: выбрал все, упорядоченное по ключу - буквально 15-19 минут(что для задачи, которую делали руками десяток-полтора человек в течении нескольких дней с ночевкой на работе - очень приемлемо.. :-) )


 
Sergey13 ©   (2008-11-19 10:28) [4]

В смысле в квери1 заранее выбрать только то, что
where id in select(второй запрос)


 
pavel_guzhanov ©   (2008-11-19 11:57) [5]

Спасибо, помогло Locate :o)


 
sniknik ©   (2008-11-19 12:26) [6]

а быстрее обработку хочешь сделать?

просто в запросе к первой таблице сделать  объединение со второй, т.е. по LEFT JOIN присоединить нужное поле (ID вроде), и тогда все будет в один цикл без локейтов, и обращаясь к одной выборке.
ускорение гарантировано. (обработки, а вот запрос может дольше, особенно если нужных индексов нет. в общем нужно время в общем смотреть... и вот тут уже не гарантия, но скорее всего будет быстрей)


 
pavel_guzhanov ©   (2008-11-19 15:20) [7]

Мне нужно, чтобы данные вынимались и в случае совпадения, и в случае несовпадения, просто они по-разному обрабатываются. а если приджойнить таблицу, то будут в результат попадать или только те, которые совпадают, или только те, которые не совпадают... По крайней мере, если сделать это так, как я понимаю :о)


 
Sergey13 ©   (2008-11-19 15:47) [8]

> [7] pavel_guzhanov ©   (19.11.08 15:20)
> Мне нужно, чтобы данные вынимались и в случае совпадения,
> и в случае несовпадения

1. In
2. Not In


 
ANB   (2008-11-19 17:42) [9]


> а если приджойнить таблицу, то будут в результат попадать
> или только те, которые совпадают, или только те, которые
> не совпадают... По крайней мере, если сделать это так, как
> я понимаю :о)

Неправильно понимаешь.

sniknik ©   (19.11.08 12:26) [6]
а быстрее обработку хочешь сделать?

просто в запросе к первой таблице сделать  объединение со второй, т.е. по LEFT JOIN присоединить нужное поле (ID вроде), и тогда все будет в один цикл без локейтов, и обращаясь к одной выборке.
ускорение гарантировано. (обработки, а вот запрос может дольше, особенно если нужных индексов нет. в общем нужно время в общем смотреть... и вот тут уже не гарантия, но скорее всего будет быстрей)

Уже все написано.
Если обрабатывается больше 50% данных обеих таблиц, то фулл-скан может оказаться быстрее, чем по индексам.


 
PEAKTOP ©   (2008-11-20 18:53) [10]

В Firebird забудь по IN. Навсегда.
Потому, как если в SELECT в условии WHERE будет IN, то подзапрос будет выполняться на каждой записи мастер-запроса. В Firebird для этого придуман такой фокус:
1) Данные IN (обычно это список ID из другой таблицы) выбираются один раз в строку, значения которой разделены разделителями. Например, символом "~", в виду его редкоупотребляемости на практике. Запрос делается один раз.
2) По мастер таблице делается запрос, в условии которго сказано: WHERE (:PMY_VALUES CONTAINING "~"||МастерТаблица.Поле||"~"). Тогда подзапрос не срабатывает на каждой записи, что влечет экспоненциально увеличение производительности, особенно на больших объемах данных.

Другой вопрос - реализация. На Firebird1.5 - однозначно через хранимую процедуру, на Firebird 2.0 и выше можно через PSQL блок. Например:
Firebird 1.5

CREATE PROCEDURE MY_PROC(
 MY_VAL INTEGER
 ....
)RETURNS(
 ....
)AS
 DECLARE VARIABLE P_VALS   VARCHAR(32000);
 DECLARE VARIABLE P_VALUE INTEGER;
BEGIN
 P_VALS = "~";
 FOR
   SELECT T1.ID FROM MY_TABLE1 T1 WHERE (T1.FIELD = MY_VAL)INTO :P_VALUE
 DO
   IF(:P_VALUE IS NOT NULL)THEN
     P_VALS = :P_VALS || :P_VALUE || "~";

 FOR
    SELECT ...
    FROM    MY_TABLE2 T2
    WHERE  (.....)
        AND  (:P_VALS LIKE "~"||T2.SOME_FIELD||"~")
    INTO   :....
 DO
   SUSPEND;
END


Firebird 2.0
EXECUTE BLOCK(
или

CREATE OR ALTER PROCEDURE MY_PROC(
 MY_VAL DOMN$INTEGER = ?MY_VAL
 ....
)RETURNS(
 ....
)AS
 DECLARE VARIABLE P_VALS   DOMN$BLOB_TEXT;
BEGIN
 SELECT "~"||LIST(T1.ID)||"~"
 FROM MY_TABLE1 T1
 WHERE (T1.FIELD = MY_VAL)
 INTO :P_VALS;

 FOR
    SELECT ...
    FROM    MY_TABLE2 T2
    WHERE  (.....)
        AND  (:P_VALS CONTAINING "~"||T2.SOME_FIELD||"~")
    INTO   :....
 DO
   SUSPEND;
END


 
sniknik ©   (2008-11-20 21:00) [11]

> Потому, как если в SELECT в условии WHERE будет IN, то подзапрос будет выполняться на каждой записи мастер-запроса.
какие страшные вещи вы рассказываете, надеюсь это сказка... ибо если не так, то из-за одного этого  нужно бросать Firebird раз и навсегда.

можно привести план выполнения для вот такого примерно запроса с IN,
SELECT * FROM Table1 t1 WHERE t1.ID IN (SELECT t2.Reft1ID FROM Table2 t2 WHERE t2.ID=2)
просто убедиться.
надеюсь понятно из в запросе, что на что ссылается.
к плану желателен реально выполняемый запрос, для гарантии что ничего не перепутано (например в подзапрос для расчетов/сравненй не попали записи из главной таблицы).



Страницы: 1 вся ветка

Текущий архив: 2009.09.13;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.012 c
15-1247038461
SP
2009-07-08 11:34
2009.09.13
Вопрос по сайту на хостинге


2-1247430369
dplz
2009-07-13 00:26
2009.09.13
Архивы и изображения :)


15-1247513346
Тима
2009-07-13 23:29
2009.09.13
Требуется помощь в написании программы


15-1247292314
Kerk
2009-07-11 10:05
2009.09.13
Обожаю, когда заказчик точно знает, чето хочет :)


2-1247156058
liveD
2009-07-09 20:14
2009.09.13
невизуальные компоненты