![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Так чтобы побыстрей работало ... [D5, MSSQL]
Vikuksa © (2002-07-08 11:44:00)Please, help!!! Есть парочка вложенных запросов, пока выполняются можно помереть со скуки. Как сделать чтобы побыстрее работало?
Vikuksa (2002-07-08 16:46:00) [1]Спасибо тебе большоо-ое!!! никогода тебя не забуду!!!
Delirium (2002-07-08 16:43:00) [2]запрос:
select myField from myTable
результат:
a
a
a
a
a
запрос:
select distinct myField from myTable
результат:
a
Vikuksa (2002-07-08 16:41:00) [3]можно поподробнее про "избавиться от повторений"?
Delirium (2002-07-08 16:36:00) [4]если хочешь избавиться от повторений - пиши
select distinct ...
Delirium (2002-07-08 16:32:00) [5]Вот некая оптимизация (не вдаваясь в смысл), надеюсь ты умеешь пользоваться 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
Vikuksa (2002-07-08 16:21:00) [6]Спасибо Delirium, бросил бедную девушку...
Vikuksa (2002-07-08 15:31:00) [7]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.
Связь между запросами идет по № человека!
ОООО!
Delirium (2002-07-08 15:21:00) [8]> Vikuksa
Возьми скрипты из Query Analyzer-а, не торопись, просто никто не сможет правильно решить задачу, если условия поставлены не чётко :)
Vikuksa (2002-07-08 15:15:00) [9]не, не так. Я НЕ МОГУ ОПИСАТЬ ГРАМОТНО! опыта маловато...
Delirium (2002-07-08 15:13:00) [10]> Vikuksa
Я опишу одну таблицу, как я понял (в основном по запросу), а ты проверь и опиши остальные - грамотно ...
T_Emitent (
sn int not null, -- Идентификатор
sng int not null, -- искомый идентификатор
ndb int not null ) -- некий определитель, типа: 1-должен, 2-оплатил
Vikuksa (2002-07-08 15:11:00) [11]Нее-е у меня во втором запросе смотрится есть ли хотябы одна запись по етому человеку
Anatoly Podgoretsky (2002-07-08 15:03:00) [12]Vikuksa (08.07.02 13:51)
Насчет декартового произведения тебе уже объяснили, если у тебя в первом запросе 1000 записей, и во втром по тысяце, то у тебя будет обработано 1 000 000 записей, быстро это не будет, надо что то менять в запросах, постараться что бы это был один запрос а не q1*q2
Vikuksa (2002-07-08 14:53:00) [13]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!
Мне нужны все кто обязан платить и среди них у кого была оплата!
Delirium (2002-07-08 14:40:00) [14]> Vikuksa
Чётко оборисуй задачу: структура таблиц и смысл полей, ожидаемый результат. Мне думается, что можно обойтись и без Delphi-йского цикла, но надо понимать проблему...
Vikuksa (2002-07-08 14:32:00) [15]Я могу прогруппировать только "sng", как только я ввожу COUNT группировка улетучивается!
Johnmen (2002-07-08 14:29:00) [16]Я что то не уловил : приведен не полный текст цикла ?
Если полный, то COUNT() !
Delirium (2002-07-08 14:27:00) [17]Хм, может в запросе цикла не получать выборку, а только считать кол-во строк ?
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)
Vikuksa (2002-07-08 14:23:00) [18]Johnmen-чик через COUNT не получается! Я в Q1 вытаскиваю записи и каждую из них проверяю на еще одно условие с помощью Q2!
Vikuksa (2002-07-08 14:23:00) [19]Johmen-чик через COUNT не получается! Я в Q1 вытаскиваю записи и каждую из них проверяю на еще одно условие с помощью Q2!
Delirium (2002-07-08 14:21:00) [20]Я думаю, стоит пользоваться переменными:
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)