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

Вниз

Так чтобы побыстрей работало ...   Найти похожие ветки 

 
Vikuksa   (2002-07-08 11:44) [0]

Please, help!!! Есть парочка вложенных запросов, пока выполняются можно помереть со скуки. Как сделать чтобы побыстрее работало?


 
Johnmen   (2002-07-08 11:54) [1]

А где же сами запросы ???


 
Val   (2002-07-08 12:10) [2]

>Vikuksa
наверное, пока выполняются, зашел сюда? :)


 
-=Sergeante=-   (2002-07-08 12:12) [3]

> Vikuksa
Надо оптимизировать запрос :)


 
Леша   (2002-07-08 12:14) [4]

Можно проидексировать таблицы.


 
Vikuksa   (2002-07-08 12:43) [5]

ADOQuery1.Active := false;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add("SELECT T_Emitent.sng FROM T_Emitent left JOIN T_Emission ON ");
ADOQuery1.SQL.Add("T_Emitent.SN = T_Emission.SNE RIGHT OUTER JOIN T_SRVEmitent ON T_Emitent.SN = T_SRVEmitent.SNE ");
ADOQuery1.SQL.Add("WHERE (T_SRVEmitent.F1 = 1) AND (T_SRVEmitent.F9 = 1) GROUP BY T_Emitent.sng ");
ADOQuery1.SQL.Add("HAVING (MAX(T_Emission.DataReg) <= CONVERT(DATETIME,""1997 - 01 - 08 00 : 00 : 00 "", 102)) ");
ADOQuery1.Active := true;
while not ADOQuery1.Eof do
begin
txt1 := ADOQuery1.fieldbyname("sng").AsString;
ADOQuery2.Active := false;
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Add("SELECT T_Emitent.sng FROM T_Emitent RIGHT JOIN T_DocFace ON T_Emitent.SN = T_DocFace.SNE ");
ADOQuery2.SQL.Add("WHERE (T_Emitent.sng = "+txt1+")");
ADOQuery2.SQL.Add("GROUP BY T_Emitent.sng, T_DocFace.F1, T_DocFace.F2, ");
ADOQuery2.SQL.Add("T_DocFace.F3 HAVING (T_DocFace.F1 = 1) AND (T_DocFace.F3 = 4)AND(T_DocFace.F2 = "+IntToStr(pp)+")");
ADOQuery2.Active := true;
if not ADOQuery2.Eof then inc(ii);
ADOQuery1.Next;
end;

ВОТ ПРИМЕРЧИК! И ЧТО????????


 
TSV   (2002-07-08 12:52) [6]

> Vikuksa (08.07.02 12:43)
Ты по-нормальному запрос написать можешь?


 
samalex1   (2002-07-08 13:27) [7]

Я что-то не понимаю, зачем функция CONVERT, может ее убрать?
Действительно, не стоит добавлять отдельно по-строчкам, можно все целиком. Или !!! используй параметрические запросы (:par заместо "+txt1+"), очень удобно, поверь, или хранимые процедуры в SQL, еще удобнее.


 
Telly_F   (2002-07-08 13:34) [8]

В добавление к Samalex1:
Еще глянь, а индексы по полям из where есть? Если есть - то какие? Попробуй с ними поработать...


 
jonik pegas   (2002-07-08 13:35) [9]

Надо развлекать пользователя чтобы не скучал
(Например ProgressBar-ом или сообщениями "Идет выполнение запроса
осталось 10% или 1 Мин" с перекидывающей папки Avi-шкой):-)
Второй запрос сделать параметрическим


 
Vikuksa   (2002-07-08 13:49) [10]

А ПО-НОРМАЛЬНОМУ ЕТО КАК?


 
Anatoly Podgoretsky   (2002-07-08 13:49) [11]

О да у тебя декартово произведение q1*q2


 
Vikuksa   (2002-07-08 13:51) [12]

Anatoly, Ты с какого дуба рухнул?
КАКОЕ ЕЩЕ ПРОИЗВЕДЕНИЕ?


 
Vikuksa   (2002-07-08 14:02) [13]

Anatoly, извини! Объясни дурехе где ты нашел произведение!


 
Johnmen   (2002-07-08 14:17) [14]

Отвечу за Anatoly Podgoretsky © :
Каждой записи из Q1 ты сопоставляешь все записи из Q2.

А Q2 в данном случае должен быть совсем другим, ведь тебе надо фактически лишь знать, есть ли хоть одна запись в Q2. (см. COUNT(*))


 
Delirium   (2002-07-08 14:21) [15]

Я думаю, стоит пользоваться переменными:

declare @d datetime set @d="19970801"

select T_Emitent.sng
from T_Emitent
left join T_Emission on T_Emitent.SN = T_Emission.SNE
right join T_SRVEmitent on T_Emitent.SN = T_SRVEmitent.SNE
where (T_SRVEmitent.F1 = 1) and (T_SRVEmitent.F9 = 1)
group by T_Emitent.sng
having max(T_Emission.DataReg) <= @D

В цикле:

declare @txt varchar(50) set @txt="song"
declare @pp int set @pp=1

select T_Emitent.sng
from T_Emitent
right join T_DocFace on T_Emitent.SN = T_DocFace.SNE
where (T_Emitent.sng = @txt)
and (T_DocFace.F1 = 1)
and (T_DocFace.F3 = 4)
and (T_DocFace.F2 = @pp)



 
Vikuksa   (2002-07-08 14:23) [16]

Johmen-чик через COUNT не получается! Я в Q1 вытаскиваю записи и каждую из них проверяю на еще одно условие с помощью Q2!


 
Vikuksa   (2002-07-08 14:23) [17]

Johnmen-чик через COUNT не получается! Я в Q1 вытаскиваю записи и каждую из них проверяю на еще одно условие с помощью Q2!


 
Delirium   (2002-07-08 14:27) [18]

Хм, может в запросе цикла не получать выборку, а только считать кол-во строк ?

declare @txt varchar(50) set @txt="song"
declare @pp int set @pp=1

select Count(*) as CountSng
from T_Emitent
right join T_DocFace on T_Emitent.SN = T_DocFace.SNE
where (T_Emitent.sng = @txt)
and (T_DocFace.F1 = 1)
and (T_DocFace.F3 = 4)
and (T_DocFace.F2 = @pp)


 
Johnmen   (2002-07-08 14:29) [19]

Я что то не уловил : приведен не полный текст цикла ?
Если полный, то COUNT() !


 
Vikuksa   (2002-07-08 14:32) [20]

Я могу прогруппировать только "sng", как только я ввожу COUNT группировка улетучивается!


 
Delirium   (2002-07-08 14:40) [21]

> Vikuksa

Чётко оборисуй задачу: структура таблиц и смысл полей, ожидаемый результат. Мне думается, что можно обойтись и без Delphi-йского цикла, но надо понимать проблему...


 
Vikuksa   (2002-07-08 14:53) [22]

T_Emitent: в ней человек, его номер, ndb.
T_SRVEmitent: обязан платить или нет.
T_Emission: кол-во платежей, когда платил.
T_DocFace: за что платил.
Связи: T_Emitent с T_SRVEmitent(ndb=1), с T_Emission(ndb-любой), с T_DocFace(ndb=2);
т.е. в T_Emitent есть человек и с ndb = 1 и c ndb = 2, а может быть только с ndb = 1!
Мне нужны все кто обязан платить и среди них у кого была оплата!


 
Anatoly Podgoretsky   (2002-07-08 15:03) [23]

Vikuksa (08.07.02 13:51)
Насчет декартового произведения тебе уже объяснили, если у тебя в первом запросе 1000 записей, и во втром по тысяце, то у тебя будет обработано 1 000 000 записей, быстро это не будет, надо что то менять в запросах, постараться что бы это был один запрос а не q1*q2


 
Vikuksa   (2002-07-08 15:11) [24]

Нее-е у меня во втором запросе смотрится есть ли хотябы одна запись по етому человеку


 
Delirium   (2002-07-08 15:13) [25]

> Vikuksa

Я опишу одну таблицу, как я понял (в основном по запросу), а ты проверь и опиши остальные - грамотно ...
T_Emitent (
sn int not null, -- Идентификатор
sng int not null, -- искомый идентификатор
ndb int not null ) -- некий определитель, типа: 1-должен, 2-оплатил


 
Vikuksa   (2002-07-08 15:15) [26]

не, не так. Я НЕ МОГУ ОПИСАТЬ ГРАМОТНО! опыта маловато...


 
Delirium   (2002-07-08 15:21) [27]

> Vikuksa

Возьми скрипты из Query Analyzer-а, не торопись, просто никто не сможет правильно решить задачу, если условия поставлены не чётко :)


 
Vikuksa   (2002-07-08 15:31) [28]

SELECT T_Emitent.SNG FROM T_Emitent left JOIN T_Emission ON
T_Emitent.SN = T_Emission.SNE RIGHT OUTER JOIN T_SRVEmitent ON T_Emitent.SN = T_SRVEmitent.SNE
WHERE (T_SRVEmitent.F1 = 1) AND (T_SRVEmitent.F9 = 1) GROUP BY T_Emitent.sng
HAVING (MAX(T_Emission.DataReg) <= "1997 - 01 - 08 ")

Это первый запрос, он вытаскивает всех людей(без повторения) кто обязан платить.

SELECT T_Emitent.sng FROM T_Emitent RIGHT JOIN T_DocFace ON T_Emitent.SN = T_DocFace.SNE
WHERE (T_Emitent.sng = "+txt1+")
GROUP BY T_Emitent.sng, T_DocFace.F1, T_DocFace.F2,
T_DocFace.F3 HAVING (T_DocFace.F1 = 1) AND (T_DocFace.F3 = 4)AND(T_DocFace.F2 = 2001)

Этот запрос проверяет есть ли у людя из списка Q1 хотя бы одна оплата, если есть то увеличивает счетчик,если нет то переходим к => записи Q1.
Связь между запросами идет по № человека!
ОООО!


 
Vikuksa   (2002-07-08 16:21) [29]

Спасибо Delirium, бросил бедную девушку...


 
Delirium   (2002-07-08 16:32) [30]

Вот некая оптимизация (не вдаваясь в смысл), надеюсь ты умеешь пользоваться NextRecordSet

set nocount on -- Чтобы не было ошибок с MultiRecordSets
-- настоятельно рекомендую для увеличения быстродействия
-- пользоваться переменными, особенно для datetime
declare @D datetime set @D="19970108"
-- "Это первый запрос, он вытаскивает всех людей(без повторения)
-- кто обязан платить."
-- сначала результат во временную таблицу
SELECT T_Emitent.SNG
into #mens
FROM T_Emitent
left JOIN T_Emission ON T_Emitent.SN = T_Emission.SNE
RIGHT JOIN T_SRVEmitent ON T_Emitent.SN = T_SRVEmitent.SNE
WHERE (T_SRVEmitent.F1 = 1)
AND (T_SRVEmitent.F9 = 1)
GROUP BY T_Emitent.sng
HAVING MAX(T_Emission.DataReg) <= @D
--"Это первый запрос..."
SELECT SNG from #mens
-- "Этот запрос проверяет есть ли у людя из списка Q1..."
-- берём сразу всех из времмной таблицы, и не вижу
-- никакого смысла в группировке
SELECT T_Emitent.sng
FROM T_Emitent
RIGHT JOIN T_DocFace ON T_Emitent.SN = T_DocFace.SNE
WHERE (T_Emitent.sng in (SELECT SNG from #mens) )
AND (T_DocFace.F1 = 1)
AND (T_DocFace.F3 = 4)
AND (T_DocFace.F2 = 2001)
-- убиваю временную таблицу
drop table #mens


 
Delirium   (2002-07-08 16:36) [31]

если хочешь избавиться от повторений - пиши select distinct ...


 
Vikuksa   (2002-07-08 16:41) [32]

можно поподробнее про "избавиться от повторений"?


 
Delirium   (2002-07-08 16:43) [33]

запрос:
select myField from myTable
результат:
a
a
a
a
a


запрос:
select distinct myField from myTable
результат:
a


 
Vikuksa   (2002-07-08 16:46) [34]

Спасибо тебе большоо-ое!!! никогода тебя не забуду!!!



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

Форум: "Базы";
Текущий архив: 2002.07.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.008 c
1-95409
BAY
2002-07-16 10:51
2002.07.29
Forms


1-95439
Kisss
2002-07-15 16:25
2002.07.29
Какая самая последняя версия библиотеки Rx?


1-95299
Ученик
2002-07-16 16:13
2002.07.29
Определение адреса конструктора


1-95387
AM
2002-07-16 09:17
2002.07.29
компонент ComboBox


3-95243
Dush
2002-07-08 15:44
2002.07.29
Сортировка с украинскими буквами





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский