Форум: "Базы";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.14;
Скачать: [xml.tar.bz2];




Вниз

Увеличение скорости обработки данных о клиентах. 


Hermit   (2002-02-14 10:12) [0]

Имеется восемь запросов, выбирающих информацию о клиентах:
1-ый: Общую информацию о клиенте, т.к. ОКПО, название и т.д.
2-ый: ОКПО клиента, среднедневные остатки
3-ый: ОКПО клиента, среднемесячные обороты
4-ый: ОКПО клиента, общие доходы от клиента
и т.д.

Необходимо свести эту информацию в одну результирующую таблицу.
Поскольку ОКПО клиента во всех выборках является уникальным, я пробегаю в цикле по всем записям первого запроса и на каждой итерации с помощью Locate нахожу соответствующие записи в остальных запросах. По окончанию итерации записываю все результаты поиска в отдельную таблицу.
Конечно это работает, но учитывая то, что кол. клиентов значительное, такая операция занимает очень длительное время. Как можно улучшить решение этой задачи?



wicked   (2002-02-14 10:24) [1]

ну раз ты не указал, под чем это крутится, то смею предположить, что у тебя клиент-серверная среда... если это так, то перенеси все запросы на серверную сторону.... т. е. никаких locate, всё расположено на сервере...
ещё момент - сгруппируй запросы по частоте использования... т. е., если данные запроса 1 часто используются с данными запроса 5 (например), то их стоит объединить в один запрос... также их стоит объединить, если выбираются похожие данные (из тех же самых таблиц)...

а если это крутится под desktop СУБД (foxpro, paradox), то могу предложить выделения некоего общего большого набора данных во временную таблицу (там будет, например, код ОКПО), и пробегать его в цикле один раз, попутно вытаскивая связанные данные из других таблиц.... соответственно, те таблицы просто необходимо проиндексировать по необходимым полям, в первую очередь - по коду ОКПО....
ну, вроде всё....



Fareader   (2002-02-14 10:27) [2]

Т.е. ОКПО у тебя является первичным ключом? А что в одном запросе не получается?



Vadim   (2002-02-14 10:45) [3]

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



Hermit   (2002-02-14 12:04) [4]

To Fareder: В одном запросе не получается. Почему? Потому что каждая из упомянутых величин расчитывается по данным из разных таблиц. Вот, например, как получаются среднедневные остатки (СДО) :
1) Выполняем запрос:
select codeokpo, nulltozero(
(select incom+
nulltozero((select sum((credit-debit)*
(:LastDate - dtend + 1))/
(:LastDate - :FirstDate + 1)
from saldo s2
where dtend between :FirstDate and :LastDate and
idacc=s1.idacc and
currency=s1.currency))
from saldo s1
where s1.idacc=A.idacc and
s1.currency=A.currency and
dtend=(select min(dtend)
from saldo
where idacc=s1.idacc and
currency=s1.currency and
dtend>=:FirstDate ))) Amount
from accowner_account A
where A.currency=:UAH and
%SQLWhere
SQLWhere - это очень обширное условие, содержащее перечень счетов (их маски), задаваемых пользователем на клиенте.
2) Записываем результат выполнения этого запроса во временную таблицу Import.
3) Выполняем запрос:
select codeokpo, sum(Amount) SDO
from Import
group by 1

В результате получаем СДО в разрезе каждого клиента.
Если же вспомнить что таких величин 8, то просто непредставляется возможным засунуть эти расчеты в один запрос.



Hermit   (2002-02-14 12:08) [5]

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



Fareader   (2002-02-14 12:09) [6]

А с какой СУБД ты работаешь?



Hermit   (2002-02-14 12:17) [7]

To wicked: Действительно речь идет о клиент-серверной среде - как источнике данных, т.е. база находиться на сервере Informix, но интересующие меня данные должны быть сохранены на локальной машине и впоследствии обрабатываться без участия сервера. (Данные с сервера забираются 1 раз в месяц). Полностью согласен с тем, что при выборке интересующих меня данных лучше всего нагрузку перенести на сервер и оттуда забирать уже сформированный набор в формате, который мне необходим. Но с учетом того, что каждая из величин расчитывается в сложных SQl запросах (смотри пример расчета СДО выше), как это зделать я пока не представляю.



Fareader   (2002-02-14 12:19) [8]

Я ддумаю можно увеличить скорость, если отказаться от вложенных запросов. Лучше использовать несколько простых запросов связывая их друг с другом Master/Detail. А это - изврат.




Форум: "Базы";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.14;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.74 MB
Время: 0.016 c
3-42948           Hermit                2002-02-14 13:38  2002.03.14  
TBatchMove и поля с строковые поля с русскими значениями


7-43206           Alexander Beliy       2001-12-08 02:03  2002.03.14  
Вопрос


1-43046           Муть                  2002-02-25 18:43  2002.03.14  
Ошибка при использовании treeview


3-42952           Font Hunter           2002-02-15 13:12  2002.03.14  
Перекодировка при перекачке данных из Paradox в Interbase


3-42958           EAlexander            2002-02-15 17:57  2002.03.14  
DOA