Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2009.09.13;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.005 c
15-1247255297
Shyrick
2009-07-10 23:48
2009.09.13
Сложение чисел в двоичной системе


15-1247313307
Claus
2009-07-11 15:55
2009.09.13
Calculator Windows


15-1247658666
картман
2009-07-15 15:51
2009.09.13
Как добавить данные из БД в полученный ранее набор данных?


15-1247603405
Юрий
2009-07-15 00:30
2009.09.13
С днем рождения ! 15 июля 2009 среда


15-1247320167
TIF
2009-07-11 17:49
2009.09.13
Windows 98





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский