union глюк или я что-то не так делаю

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
Gall
Сообщения: 8
Зарегистрирован: 05 окт 2005, 14:48

union глюк или я что-то не так делаю

Сообщение Gall » 16 янв 2006, 14:13

fierbird 1.5.2 под линуха
создаю сиквел с использованием union из двух частей
если поотдельности эти части запускать, тo IBExpert показывает Execute time равный милисекундам, если же обьединяю то результат уже 3 секунды. при этом тот же самый IBExpert в Performance analysis показывает ображение к одной таблице около 500000 раз, хотя в таблицах не более 500 записей.

весь этот тормоз возникает из-за того что я считаю суммы внутри запросов

(
...select sum( ssm.zena*ssm.kolvo*(select vk_.kyrs from valuta_kyrs vk_ where
vk_.date_ =(select max(vk1_.date_) from val.....
)

если заместо union использую union all и убираю order by то запрос выполнется моментально.

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

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 16 янв 2006, 15:27

Да, подзапрос действительно тяжелый. Я бы на твоем месте загнал всю эту бодягу SP и развернул сложный подзапрос в пару простых.

Gall
Сообщения: 8
Зарегистрирован: 05 окт 2005, 14:48

Сообщение Gall » 16 янв 2006, 15:59

Dimitry Sibiryakov писал(а):Да, подзапрос действительно тяжелый. Я бы на твоем месте загнал всю эту бодягу SP и развернул сложный подзапрос в пару простых.
а как я это сделаю в ХП? для каждого елемента надо считать его цену в выбраной валюте, потом всё равно юнион делать.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 16 янв 2006, 16:13

уж сколько раз советовали - храните ТЕКУЩИЕ (последние) значения курса валюты, чтобы не шарить по всей таблице валют запросами select max(course_date)...

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Re: union глюк или я что-то не так делаю

Сообщение hvlad » 16 янв 2006, 18:11

Gall писал(а):fierbird 1.5.2 под линуха
создаю сиквел с использованием union из двух частей
если поотдельности эти части запускать, тo IBExpert показывает Execute time равный милисекундам, если же обьединяю то результат уже 3 секунды.
fetch в первом случае, fetch all (внутри сервера, дабы удалить дубликаты) во втором
Gall писал(а):если заместо union использую union all и убираю order by то запрос выполнется моментально.
Т.к. сервер перестаёт выполнять весь запрос
Gall писал(а):что делать? может в настройках сервера что-то надо менять? или вообще нельзя делать юнионы запросам с такой структурой?
Запросы писать нормальные (а не "сиквелы") к нормально спроектированным стр-рам данных

Gall
Сообщения: 8
Зарегистрирован: 05 окт 2005, 14:48

Сообщение Gall » 17 янв 2006, 13:32

kdv писал(а):уж сколько раз советовали - храните ТЕКУЩИЕ (последние) значения курса валюты, чтобы не шарить по всей таблице валют запросами select max(course_date)...
дело в том, что я ищу не последнюю дату, а дату сответствующую дню закупки либо продажи. если есть какой-то метод для ускорения такого поиска, то подскажите.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 17 янв 2006, 13:47

Сделай descending index по дате в журнале курсов.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 17 янв 2006, 13:52

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

Gall
Сообщения: 8
Зарегистрирован: 05 окт 2005, 14:48

Сообщение Gall » 17 янв 2006, 14:52

Merlin писал(а):Сделай descending index по дате в журнале курсов.
время выборки уменьшилось в два раза, большое спасибо


kvd, строить систему чтобы курс существовал на каждый день не очень удобно, но видимо необходимо.
тогда встречный вопрос - поддерживает ли firebird какие-либо аналоги jobs из MSSQLServer? Я поискал, но не нашел.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 17 янв 2006, 15:08

kdv писал(а):
а дату сответствующую дню закупки либо продажи
опять же, тогда надо организовать систему (таблицу курсов валют) так, чтобы курс существовал на каждый день. И при выборке просто искать соответствие дате закупки или продажи, а не по max.
Не всегда прокатывает. Вспомни дефолт - пять раз на дню курс менялся. Самое простое - денормализация. То есть, при выполнении соответсвующего действия с документом (зависит от политики фирмы, начало оформления или утверждение) брать курс из журнала и укладывать в заголовок документа.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 17 янв 2006, 15:24

2 Gall

Спробуй ещё такую конструкцию

Код: Выделить всё

Select Sum(Doc.Cena*Doc.Kolvo*R1.Rate)
From Doc Join Rates R1 On R1.Valuta=Doc.Valuta
  And R1.Data=(Select Max(R2.Data)
                       From Rates R2 
                       Where R2.Valuta=Doc.Valuta
                           And R2.Data<=Doc.Data)
В принципе почти то же самое, но может оказаться шустрее.

Ответить