Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Медленно работает MSSQL сервер [D7, MSSQL]


Страницы:   1 2

ch_victor ©   (2004-02-02 10:45:00) 

Добрый день всем!!!
Я слышал что MSSQL сервер медленно работает с user-defined function, но не думал, что настолько медленно

обьясняю суть задачи:
имееется 2 таблицы
1 таблица частолетающих пассажиров
2 таблица полетов этих пассажиров
по правилам частолетающим пассажиром является тот кто совершает полеты не реже раз в год
поэтому нужно связать эти две таблицы и найти таких пассажиров, у которых промежуток между двумя полетами более года

я сделал view в котором выводятся такие пассажиры
в нем использую функцию которая вычисляет есть ли большой промежуток между полетами, в функции использую курсор который вытаскивает построчно полеты определенного пассажира и сравнивает даты полета

так вот эта задача отрабатывает очень долго (около часа), хотя количество записей в таблицах не очень большое в первой 10000 записей, а во второй 60000

можно ли обойтись без курсора в функции, потому что я так думаю тормозит из-за него, какие будут предложения?


Fay   (2004-02-02 15:55:00) [1]

8)


kaif   (2004-02-02 15:53:00) [2]

Пардон, агрегатное поле в группировке не нужно (скопировал, забыл стереть):
select extract(year from date1), passanger_id, count(*)
from mytable
group by extract(year from date1), passanger_id


Рекомендую хотя бы попробовать такой запрос.


kaif   (2004-02-02 15:51:00) [3]

Я бы просто сгруппировал полеты по пассажирам и годам:
select extract(year from date1), passanger_id, count(*)
from mytable
group by extract(year from date1), count(*), passanger_id

(это правда синтаксис IB, но уверен в MSSQL есть подобная возможность)

Это покажет по годам, как народ летает. Я уверен, что заказчика устроит такой отчет. Совсем не обязательно ловить промежутки дат. Из того, что чел 2 раза в жизни полетел (один раз 22 декабря, а второй раз - обратно 5 января следующего года) еще никак не следует, что он часто летает. Лучший отчет - погодовой. Так сказать хит-парад часто летающих пассажиров. И работать это будет за 1 сек.


Fay   (2004-02-02 15:44:00) [4]

Эти тебе нужны?
select distinct q.client_id
from
(select
client_id
from [таблица полётов]
group by client_id, datepart(y, servicedate)
having count(*) = 0
) q


Ega23   (2004-02-02 14:35:00) [5]

Конечно, смотреть тех, у которых есть Дата_полёта>=GetDate()-365


SergSuper   (2004-02-02 14:28:00) [6]

А не имеет смысл взять какой-нибудь промежуток и считать сколько раз какой клиент летал?


Fay   (2004-02-02 13:43:00) [7]

Код (+DDL) в студию


ch_victor   (2004-02-02 12:52:00) [8]

таже самая задача, на том же сервере но под ораклом отрабатывает действительно за пару секунд
так что кто виноват кривые руки или действительно MSSQL не самый быстрый


Nikolay M.   (2004-02-02 12:49:00) [9]


> > MSSQL - очень быстрый. Но может тормозить в режиме совместимости
> > с CurveHands.
> а как посмотреть не в этом ли режиме он работает?

:)))))
Если задача, которая должна отрабатывать за пару секунд, выполняется порядка часа, значит имеет быть место несовместимость :))


ch_victor   (2004-02-02 12:43:00) [10]


> MSSQL - очень быстрый. Но может тормозить в режиме совместимости
> с CurveHands.


а как посмотреть не в этом ли режиме он работает?


Nikolay M.   (2004-02-02 12:26:00) [11]

13 секунд - тоже немало. Все-таки попробуй еще с курсором.


Fay   (2004-02-02 12:07:00) [12]

MSSQL - очень быстрый. Но может тормозить в режиме совместимости с CurveHands.


ch_victor   (2004-02-02 12:05:00) [13]

последний вариант
> Nikolay M. © (02.02.04 11:56) [14]
работает, и не очень долго около 13 секунд, спасибо за помощь


Nikolay M.   (2004-02-02 11:56:00) [14]

У меня работает:

SELECT DISTINCT(client_id)
FROM transaction_ tr1
WHERE DATEDIFF(Day, (SELECT ISNULL(MAX(tr2.servicedate), tr1.servicedate) FROM transaction_ tr2 WHERE (tr1.client_id = tr2.client_id) AND (tr2.servicedate < tr1.servicedate)), tr1.servicedate) > 365


Anatoly Podgoretsky   (2004-02-02 11:53:00) [15]

Нестыковки этим не кончаются
Возьмем три полета
P1 - 0
P2 - 364
P3 - 380

по условию P3-P1 > юольше 365, такие полеты найдены, хотя P3-P2 < 365

Второй вариант
P1 - 1.01.2000
P2 - 5.01.2000

опять же по условию разница между полетами < 365, а сейчас 2004 год, условие получается вечное. Можете надо разница между текущей датой и датой полета <= 365 дней. Тогда сработает (Max(D)-Now) <= 365 GROUP BY client_id другие условия

Нужна четкая формулировка задачи.


sniknik   (2004-02-02 11:48:00) [16]

хотя чего думать то, прыгать нужно. ;о))
обьеденение нужно не с таблицей делать а с вложенным подзапросом в котором по самообьеденению разницу дат высчитывать, вот и получится в результирующем запросе с максимальной и минимальной "дыркой".


ch_victor   (2004-02-02 11:42:00) [17]


> sniknik © (02.02.04 11:34) [10]
> хотя нет не все, тебе ведь "дырки" между соседними нужны
> а не минимальный и максимальный. :( еще надо подумать.

вот именно почему я курсор и использовал


sniknik   (2004-02-02 11:34:00) [18]

хотя нет не все, тебе ведь "дырки" между соседними нужны а не минимальный и максимальный. :( еще надо подумать.


ch_victor   (2004-02-02 11:31:00) [19]

Nikolay M. © (02.02.04 11:15) [7]


не работает запрос

An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.

и не совсем понятно в чем преимущества использования временной таблицы перед view c функцией внутри?


sniknik   (2004-02-02 11:29:00) [20]

еще к примеру можно

SELECT T1.client_id, T1.lastname, T1.firstname, Max(T2.servicedate) AS MaxServicedate, Min(T3.servicedate) AS MinServicedate
FROM (client T1 LEFT JOIN transaction T2 ON T1.client_id = T2.client_id) LEFT JOIN transaction T3 ON T1.client_id = T3.client_id
GROUP BY T1.client_id, T1.lastname, T1.firstname;

это на access (не могу сейчас на MSSQL проверить) так что придется тебе синтаксис поправить.
но смысл ясен (?) остается только сравнить MaxServicedate и MinServicedate.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо