|
|
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Сообственно вопрос следующий: Есть три таблицы GOODS - товары 10000 записей ID PARENT NAME CUST - клиенты 2000 записей ID PARENT NAME DOC - отгрузки (YY-год, ММ-месяц и индекс GOODS,CUST,YY,MM) - 100 000 записей GOODS CUST YY MM QTY PRICE Нужно выдать результаты в виде таблицы(): Группа Товаров, Кол-во Январь, Кол-во Февраль, ..., Кол-во Декабрь, Кол-во Итого; Создал две рекурсивные процедуры, которые отбирают нужных клиентов и товары и сделал ХП Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Все работает точно до копейки, но быстродействие ~ 20 минут , если выбирать корневую группу товаров и клиентов. Может есть какие-то другие решения ? Best regards, Dnico. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.08.2004, 16:36:40 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
А попробуй от клентов, скажем, плясять : Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.08.2004, 17:14:47 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Ну вообщем-то выигрышь составил 12%. Это уже радует ... Best regards, Dnico. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.08.2004, 17:28:50 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Ну что еще посоветовать можно не видя текстов процедур и планов... Если там все нормально, то может стоит завести еще одну табличку с агрегатами по клиенту, товару (группе товаров?) за месяц. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.08.2004, 18:00:08 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Dnico ...быстродействие ~ 20 минут ... А если так попробывать: [/quot] CREATE PROCEDURE peDocGidCid (GID INTEGER, CID INTEGER) RETURNS (NAME CHAR(40), QTY1 DOUBLE PRECISION, QTY2 DOUBLE PRECISION, QTY3 DOUBLE PRECISION, QTY4 DOUBLE PRECISION, QTY5 DOUBLE PRECISION, QTY6 DOUBLE PRECISION, QTY7 DOUBLE PRECISION, QTY8 DOUBLE PRECISION, QTY9 DOUBLE PRECISION, QTY10 DOUBLE PRECISION, QTY11 DOUBLE PRECISION, QTY12 DOUBLE PRECISION QTY DOUBLE PRECISION) AS DECLARE VARIABLE MM INTEGER; BEGIN SELECT NAME FROM GOODS WHERE GID = :GID INTO :NAME; QTY = 0; QTY1 = 0; QTY2 = 0; QTY3 = 0; QTY4 = 0; QTY5 = 0; QTY6 = 0; QTY7 = 0; QTY8 = 0; QTY9 = 0; QTY10 = 0; QTY11 = 0; QTY12 = 0; FOR SELECT MM,QTY FROM DOC WHERE GID = :GID AND CID = :CID INTO :MM,:QTY DO BEGIN IF (MM = 1) THEN QTY1 = QTY1 + QTY; ELSE IF (MM = 2) THEN QTY2 = QTY2 + QTY; ELSE IF (MM = 3) THEN QTY3 = QTY3 + QTY; ELSE IF (MM = 4) THEN QTY4 = QTY4 + QTY; ELSE IF (MM = 5) THEN QTY5 = QTY5 + QTY; ELSE IF (MM = 6) THEN QTY6 = QTY6 + QTY; ELSE IF (MM = 7) THEN QTY7 = QTY7 + QTY; ELSE IF (MM = 8) THEN QTY8 = QTY8 + QTY; ELSE IF (MM = 9) THEN QTY9 = QTY9 + QTY; ELSE IF (MM = 10) THEN QTY10 = QTY10 + QTY; ELSE IF (MM = 11) THEN QTY11 = QTY11 + QTY; ELSE IF (MM = 12) THEN QTY12 = QTY12 + QTY; END QTY = QTY1 + QTY2 + QTY3 + QTY4 + QTY5 + QTY6 + QTY7 + QTY8 + QTY9 + QTY10 + QTY11 + QTY12; END [/quot] SELECT NAME... - лучше бы перенести во внешнюю ХП (которая выбирает GID) чтоб неделать ее на каждый CID... и QTY =... - туда же... ELSE IF... заменить на CASE... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 06:36:10 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
olol Спасибо, мне эта идея тоже приходила в голову и я ее использовал в старых версиях FB, когда небыло CASE. Сейчас про такой подход забыл ... Попробую .... Best regards, Dnico. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 10:31:50 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Увы ... Одно и тоже. Best regards, Dnico. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 11:15:05 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
автор Базу на всякий случай бакап/ресторни... ...две рекурсивные процедуры, которые отбирают нужных клиентов и товары... Можно хоть на них взглянуть... вдруг собака там зарыта... Почему рекурсивные? и почему две? Записей в принципе не так уж много, но любое лишнее телодвижение в тысячах на тысячу могут дать большие объемы работы... Трудно судить о задаче... но если нужен отчет за год по клиентам, то я бы сделал приблизительно так: [quot] CREATE PROCEDURE psDocYY (YY INTEGER) RETURNS (СNAME CHAR(40), GNAME CHAR(40), QTY1 DOUBLE PRECISION, QTY2 DOUBLE PRECISION, QTY3 DOUBLE PRECISION, QTY4 DOUBLE PRECISION, QTY5 DOUBLE PRECISION, QTY6 DOUBLE PRECISION, QTY7 DOUBLE PRECISION, QTY8 DOUBLE PRECISION, QTY9 DOUBLE PRECISION, QTY10 DOUBLE PRECISION, QTY11 DOUBLE PRECISION, QTY12 DOUBLE PRECISION) AS DECLARE VARIABLE GID INTEGER; DECLARE VARIABLE CID INTEGER; DECLARE VARIABLE GOODS INTEGER; DECLARE VARIABLE CUST INTEGER; BEGIN GOODS = 0; CUST = 0; FOR SELECT DISTINCT GOODS,CUST FROM GOODS WHERE YY = :YY INTO :GID,:CID DO BEGIN IF (GID <> :GOODS) THEN BEGIN GOODS = GID; SELECT NAME FROM GOODS WHERE GID = :GID INTO :GNAME; END IF (CID <> :CUST) THEN BEGIN CUST = CID; SELECT NAME FROM CUST WHERE CID = :CID INTO :CNAME; END EXECUTE PROCEDURE peDocGidCid (:GID, :CID) RETURNING_VALUES :QTY1,:QTY2,:QTY3,:QTY4,:QTY5,:QTY6, :QTY7,:QTY8,:QTY9,:QTY10,:QTY11,:QTY12; END END ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 13:14:00 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
автор Поторопился и SUSPEND; забыл поставить... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 13:25:41 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Вот рекурсия, вибирает все товары принадлежащие группе (IDD)CREATE PROCEDURE GETGOODS ( IDD VARCHAR(10)) RETURNS ( ID VARCHAR(10), PID VARCHAR(10), NAME VARCHAR(100), ISF SMALLINT) AS BEGIN FOR SELECT ID, PARENT, NAME,ISF FROM GOODS WHERE PARENTID = :IDD INTO :ID, :PID, :NAME, :ISF DO BEGIN IF (:ISF = 1) THEN FOR SELECT ID, PID, NAME, ISF FROM GETGOODS (:ID) INTO :ID, :PID, :NAME, :ISF DO SUSPEND; ELSE SUSPEND; END END Аналогично и по клиенту. И сам запрос (С планами все ок на 100%): авторSELECT SUM(CASE WHEN D.MM = 1 THEN QTY ELSE 0 END), ..... SUM(CASE WHEN D.MM = 12 THEN QTY ELSE 0 END) FROM GETCUST(:CID) C JOIN DOC D ON (C.ID = D.CUST) JOIN GETGOODS(:GID) G ON (G.ID = D.GOODS) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. Best regards, Dnico. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 16:50:03 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Мимопроходящий - может хоть ссылочку какую тиснешь? А то совсем закопался. Никаких идей ... Best regards, Dnico. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 17:17:27 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Dnico Мимопроходящий - может хоть ссылочку какую тиснешь? А то совсем закопался. Никаких идей ... На какую тему? Я ж в этом обсуждении не участвую. На http://ibase.ru про деревья всё прочитал? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 17:21:56 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Да все вроде-бы читал ... только не помогает Best regards, Dnico. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 17:25:36 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
DnicoДа все вроде-бы читал ... только не помогает Ну, тогда попробуй подумать. Иногда помогает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 17:29:56 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Ладно, тему можно закрывать ... добился 2 минут . Думаю это предел. Best regards, Dnico. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 18:21:13 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
У тебя много чтений GOODS - пляши от них ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 18:47:53 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
У тебя много чтений GOODS - пляши от них ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2004, 18:49:31 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Может я чего то не понимаю, но помоему для корневых групп товаров и клиентов GETGOODS и GETCUST выдадут все записи, что составит 10000 * 2000 = ...дофига получается комбинаций и для каждой будет считаться SUM... (при ее наличии в DOC)... Если там всего 100 000 записей, то их не будет для каждой и по одной за год... Не лучше ли плясать от DOC получив сначала ...DISTINCT GOODS,CUST FROM DOC WHERE YY = :YY (тогда лишних комбинаций не будет), а уж потом проверять на их принадлежность GETGOODS и GETCUST и считать SUM... P.S. что-то я не заметил проверки на YY !!! (помесячно за все года что ли...) и я бы ID записей не делал VARCHAR(10) !!! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2004, 07:23:01 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
ololМожет я чего то не понимаю, но помоему для корневых групп товаров и клиентов GETGOODS и GETCUST выдадут все записи, что составит 10000 * 2000 = ...дофига получается комбинаций и для каждой будет считаться SUM... (при ее наличии в DOC)... Если там всего 100 000 записей, то их не будет для каждой и по одной за год... Не лучше ли плясать от DOC получив сначала ...DISTINCT GOODS,CUST FROM DOC WHERE YY = :YY (тогда лишних комбинаций не будет), а уж потом проверять на их принадлежность GETGOODS и GETCUST и считать SUM... Да, это вот интересное решение. Попробую. ololP.S. что-то я не заметил проверки на YY !!! (помесячно за все года что ли...) Проверка такая есть конечно, просто сейчас в таблице лежит один год. olol и я бы ID записей не делал VARCHAR(10) !!! К сожалению это отголоски 1С. Best regards, Dnico. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2004, 09:40:09 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. А не подскажешь, почему так получается? Я так понимаю, что GetGoods выполняется для каждой строки, получившейся при объединении DOC и GETCUST? Абстрактно говоря, оптимизатор рассматривает GetGoods как коррелированный подзапрос? По идее можно сначала вычитать из нее все один раз и результаты объединять. Или все не так? А если так, то в FB 2 есть какие-нибудь планы по этому поводу? Может какие-то хинты ввести, чтобы можно было помочь оптимизатору в таких случаях. И если то что я написал более-менее похоже на правду - то для того чтобы уменьшить время выполнения запроса, можно результаты выборки из GetGoods вставлять во временную табличку и затем с ней и join-ить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2004, 10:02:01 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
ЛентяйА не подскажешь, почему так получается? Я так понимаю, что GetGoods выполняется для каждой строки, получившейся при объединении DOC и GETCUST? Абстрактно говоря, оптимизатор рассматривает GetGoods как коррелированный подзапрос? По идее можно сначала вычитать из нее все один раз и результаты объединять. Или все не так? Насколько я понимаю - да GetGoods вызывается многократно. Но не потому что оптимизатор считает его кореллированным, а потому, что сейчас нет способа скешировать результаты выборки из процедуры и использовать их несколько раз. ЛентяйА если так, то в FB 2 есть какие-нибудь планы по этому поводу? Есть ;) ЛентяйИ если то что я написал более-менее похоже на правду - то для того чтобы уменьшить время выполнения запроса, можно результаты выборки из GetGoods вставлять во временную табличку и затем с ней и join-ить.Или пользоваться другой структурой дерева, позволяющей получить необходимую выборку одним запросом без рекурсии. А временную таблицу если и использовать, то для результатов GETCUST - их должно быть много меньше ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2004, 10:29:43 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
hvladНасколько я понимаю - да GetGoods вызывается многократно. Но не потому что оптимизатор считает его кореллированным, а потому, что сейчас нет способа скешировать результаты выборки из процедуры и использовать их несколько раз.Спасибо за разъяснения. ЛентяйА если так, то в FB 2 есть какие-нибудь планы по этому поводу? hvladЕсть ;)?Улыбка-то, надеюсь, не ехидная? hvladИли пользоваться другой структурой дерева, позволяющей получить необходимую выборку одним запросом без рекурсии. А можно еще две процедуры в одну объединить и к ней join-ить hvladА временную таблицу если и использовать, то для результатов GETCUST - их должно быть много меньшеУгу, так лучше будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2004, 11:53:32 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Рекурсивные процедуры - 17 сек Временные таблицы CUST & GOODS - 8 сек Best regards, Dnico. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2004, 12:10:59 |
|
||
|
Опять про деревья и время выполнения ...
|
|||
|---|---|---|---|
|
#18+
Ну, по сравнению с 20 минутами очень даже неплохо... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2004, 12:27:20 |
|
||
|
|

start [/forum/topic.php?fid=40&msg=32646564&tid=1578076]: |
0ms |
get settings: |
7ms |
get forum list: |
10ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
148ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
| others: | 221ms |
| total: | 458ms |

| 0 / 0 |
