Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Оптимизация запроса

21K
12 марта 2007 года
SMS
7 / / 23.11.2006
Есть запрос, который подсчитывает остаток товара из табл. nakladnaya и orders, а затем выводит данные в столбец по строкам для каждого элемента таблицы tovar.Вот код
"select ID_TOVAR ,
ifnull(select sum(o.qtty) from orders o, nakladnaya n where n.NAKL_NOMER =o.NAKL_NOMER
and o.GOOD_ID =tovar.ID_TOVAR and n.TYPE_NAKL in(1,2)-
select sum(o.qtty) from orders o , nakladnaya n where n.NAKL_NOMER =o.NAKL_NOMER
and o.GOOD_ID =tovar.ID_TOVAR and n.TYPE_NAKL in(3,4),0 )
from tovar;
Пробовал ли кто нибудь оптимизировать его?Дело в том, что на mySQL 3000 строк табл. товар и около 6000 строк из price выполняются за 0.5 сек, а вот для HSQLDB это занимает почти минуту! А мне нужна встраиваемая БД.
Спасибо.
385
13 марта 2007 года
SomewherSomehow
477 / / 25.07.2004
возможно так будет быстрее, если я конечно правильно понял суть.
Код:
select
    t.ID_TOVAR
    ifnull(sum(o1.qtty)-sum(o2.qtty),0)
from
    orders o1,
    nakladnaya n1,
    orders o2,
    nakladnaya n2,
    tovar t
where
    n1.NAKL_NOMER =o1.NAKL_NOMER and
    n1.TYPE_NAKL in (1,2) and
    n2.NAKL_NOMER =o2.NAKL_NOMER and
    n2.TYPE_NAKL in(3,4) and
    t.ID_TOVAR = o1.GOOD_ID and
    t.ID_TOVAR = o2.GOOD_ID

(не проверял)
21K
13 марта 2007 года
SMS
7 / / 23.11.2006
Спасибо, S.S.
Мысль присваивать alias очень интересна.
Ваш запрос сейчас дает одну строку, а мне нужена таблица типа:
id_tovar Ostatok
1 10
2 12 и т.д.
Спасибо.
385
13 марта 2007 года
SomewherSomehow
477 / / 25.07.2004
Т.е. он выводит таблицу, но в котой всего одна строчка?
1
14 марта 2007 года
kot_
7.3K / / 20.01.2000
Цитата: SMS
Спасибо, S.S.
Мысль присваивать alias очень интересна.
Ваш запрос сейчас дает одну строку, а мне нужена таблица типа:
id_tovar Ostatok
1 10
2 12 и т.д.
Спасибо.


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

21K
14 марта 2007 года
SMS
7 / / 23.11.2006
Спасибо, kot_.
Если вы имели ввиду такой код:

Код:
select
    t.ID,
    ifnull(sum(o1.qtty)-sum(o2.qtty),0)
from
    orders o1,
    nakladnaya n1,
    orders o2,
    nakladnaya n2,
    tovar t
where
    n1.NAKL_NOMER =o1.NAKL_NOMER and
    n1.TYPE_NAKL in (1,2) and
    n2.NAKL_NOMER =o2.NAKL_NOMER and
    n2.TYPE_NAKL in(3,4) and
    t.ID = o1.GOOD_ID and
    t.ID = o2.GOOD_ID
        GROUP BY  t.ID

, то он выводит просто пустую таблицу без единой строки, в отличие от предыдущего варианта.
Вот такой работает, но это не то, что нужно:confused: :
Код:
select
    t.ID,
    ifnull(sum(o1.qtty),0)
from
    orders o1,
    nakladnaya n1,
    tovar t
where
    n1.NAKL_NOMER =o1.NAKL_NOMER and
    n1.TYPE_NAKL in (1,2) and
   
    t.ID = o1.GOOD_ID
group by t.id


Буду рад услышать критику.:)
1
15 марта 2007 года
kot_
7.3K / / 20.01.2000
Ваша проблема в том, что задав вопрос, вы не описали зависимость таблиц - поэтому то у вас и выводится каша (я так подозреваю).
Без этого все что вам можно посоветовать - использовать группировку - но я правда не стал писать, результат ее весьма не определен. :)
Я бы попытался составить такой запрос (естественно на правильность он не претендует, учитывая вышесказанное)
 
Код:
select
    t.ID_TOVAR,
    ifnull(sum(o1.qtty),0)-ifnull(sum(o2.qtty),0) AS RES_QTTY
from
     tovar t LEFT JOIN orders o1 ON t.ID_TOVAR = o1.GOOD_ID
    INNER JOIN nakladnaya n1 ON n1.NAKL_NOMER =o1.NAKL_NOMER AND n1.TYPE_NAKL in (1,2)
    LEFT JOIN orders o2 ON t.ID_TOVAR = o2.GOOD_ID
    INNER JOIN nakladnaya n2 ON n2.NAKL_NOMER =o2.NAKL_NOMER AND n2.TYPE_NAKL in(3,4)
       
GROUP BY t.ID_TOVAR

Что то типа подобного - но как понимаете моделировать все это в полночь особого желания нет, выстраивать правильно джойны - тоже, потому к данному коду стоит относится очень критично. Возможно, необходимо будет изменить последовательность джойнов - это уже вам, как говорится и карты...
З.Ы. Так как вопрос не был о структуре собственно базы - поэтому комментировать не буду. Но сам по себе запрос так и просится быть разделенным на две вьюхи.
21K
15 марта 2007 года
SMS
7 / / 23.11.2006
Спасибо, kot_!
Действительно, я новичок на форумах и привык все сам делать, вот и не задал вопрос правильно.Sorry!
По структуре.
Есть 3 табл. Накладная (nakladnaya), Заказы(orders), Товары(tovar).
Заказы связаны внешним ключом с Накладной по полю(nakl_nomer).
Требуется вывести остатки по каждому товару.
Т.к. накладные на расход и на приход в одной таблице, то приходиться пробегаться два раза минимум.
Что касается предложенного вами варианта, то он обрабатывается 1622ms, но выдает 0 rows.Как, впрочем и у меня.
Если же пользоваться вьюшками( я как бы разделил запрос на приходную и расходную часть), то рез-тат тот же.
Короче пока ищу еще варианты, но буду рад любой мысли.
Спасибо.
1
15 марта 2007 года
kot_
7.3K / / 20.01.2000
Цитата: SMS
Спасибо, kot_!
Действительно, я новичок на форумах и привык все сам делать, вот и не задал вопрос правильно.Sorry!
По структуре.
Есть 3 табл. Накладная (nakladnaya), Заказы(orders), Товары(tovar).
Заказы связаны внешним ключом с Накладной по полю(nakl_nomer).
Требуется вывести остатки по каждому товару.
Т.к. накладные на расход и на приход в одной таблице, то приходиться пробегаться два раза минимум.
Что касается предложенного вами варианта, то он обрабатывается 1622ms, но выдает 0 rows.Как, впрочем и у меня.
Если же пользоваться вьюшками( я как бы разделил запрос на приходную и расходную часть), то рез-тат тот же.
Короче пока ищу еще варианты, но буду рад любой мысли.
Спасибо.



Выложи в текстовых файлах с разделителями пример (но плиз пример, а не все данные) твоих данных и скрипты по созданию таблицы. Будет время - я гляну - возможно проблема вовсе и не в запросе. Кроме того - пытались поменять условия отношения между товаром и счетом?

21K
15 марта 2007 года
SMS
7 / / 23.11.2006
Цитата: kot_
Кроме того - пытались поменять условия отношения между товаром и счетом?


Не понял как поменять отношения?
Может м/у накладной и заказом?
Вложил.Скрипты.
Спасибо.

1
16 марта 2007 года
kot_
7.3K / / 20.01.2000
Решения задачи может быть два. Первое - это вот такой запрос - практически тоже что приведено в вопросе (с NULL-значениями разберешься сам) -
 
Код:
select tovar.ID, (SELECT     SUM(orders.qtty) AS PRIH
FROM         orders INNER JOIN
                      nakladnaya ON orders.nakl_nomer = nakladnaya.nakl_nomer
AND nakladnaya.type_nakl IN (1, 2) where tovar.ID = orders.GOOD_ID ) - (SELECT     SUM(o2.qtty) AS RASH
FROM         orders o2 INNER JOIN
                      nakladnaya n2 ON o2.nakl_nomer = n2.nakl_nomer
AND n2.type_nakl IN (3, 4) where tovar.ID = o2.GOOD_ID)  from tovar

второй - использование представлений (view) или/и ХП (что оптимальней как правило).
Третий - фактически тоже самое, но с использованием временных таблиц.
По другому оптимизировать можно только изменив структуру базы.
1
16 марта 2007 года
kot_
7.3K / / 20.01.2000
Естественно, есть еще вариант - вычислять остаток на стороне клиента.
21K
16 марта 2007 года
SMS
7 / / 23.11.2006
Очередное спасибо.
Я тоже пришел к выводу о создании временных или точнее промежуточных таблиц.
Пробовал варианты с view, но скорость не увеличивается значительно, а в перспективе роста базы еще и усугубиться.
Спасибо за советы.
Думаю тему можно закрыть.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог