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

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.017 c
3-95255
Oleon
2002-07-08 17:41
2002.07.29
Непонятный формат файла.


1-95293
BlackGrin
2002-07-15 11:06
2002.07.29
Определение нажатого кнопки


3-95272
tatiana
2002-07-09 14:01
2002.07.29
Объединение запросов TQuery


3-95269
Loco
2002-07-09 15:43
2002.07.29
Query


3-95216
PashketSiniz
2002-07-08 11:38
2002.07.29
???????