Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Увеличить скорость расчета остатков
|
|||
|---|---|---|---|
|
#18+
В связи с тем, что объем таблиц для прихода и расхода увеличивается, расчет остатков стал длиться очень долго. Расчитываются остатки путем вычитания из прихода всего расхода. Не хотелось бы заниматься "резкой" таблиц по периодам, а м.б. поменять алгоритм или что нибудь еще... Товары приходуются в упаковках, расходоваться же могут упаковками и штуками. Пример выборки, которая и отрабатывает очень долго: SELECT r.id,r.cnt,sum(IIF(e.log=0,e.cnt,0)) as e_cnt,sum(IIF(e.log=1,e.cnt,0)) as e_cnt_p,; MAX(ALLTRIM(m.name)+IIF(ISNULL(p.name),'',' '+ALLTRIM(p.name))) as medname,; MAX(r.retailprice) as retailprice,; 000000000000+MAX(IIF(n.countinpack=0,1,n.countinpack)) as cntinpack, r.barcode as barcode,MAX(r.apptyme) as app_tyme ,; max(TTOD(d.date)) as date,'' as inv_no; FROM receipts r,expenses e,documents d,medications m,nomenclatures n LEFT OUTER JOIN produsers p ON n.prod_id=p.id; WHERE r.id=e.rcpt_id AND n.id=r.nom_id AND n.med_id=m.id AND d.id=r.doc_id AND d.closed AND d.store_id=goApp.nStoreHouse_ID AND d.closed; GROUP BY r.id,r.cnt, r.barcode ; UNION all; select r.id,r.cnt,0 as e_cnt,0 as e_cnt_p,; ALLTRIM(m.name)+IIF(ISNULL(p.name),'',' '+ALLTRIM(p.name)) as medname,r.retailprice,; 000000000000+IIF(n.countinpack=0,1,n.countinpack) as cntinpack, r.barcode as barcode,r.apptyme as app_tyme,; TTOD(d.date) as date,'' as inv_no; FROM receipts r,documents d,medications m,nomenclatures n LEFT OUTER JOIN produsers p ON n.prod_id=p.id ; WHERE n.id=r.nom_id AND n.med_id=m.id AND d.id=r.doc_id AND d.closed AND d.store_id=goApp.nStoreHouse_ID AND d.closed; AND NOT r.id in (select DISTINCT e.rcpt_id as id FROM expenses e ); INTO CURSOR _rest READWRITE далее куски кода отрабатыват достаточно быстро. В них происходит: REPLACE ALL e_cnt WITH cnt-e_cnt-CEILING(e_cnt_p/cntinpack),; e_cnt_p WITH IIF(MOD(e_cnt_p,cntinpack)=0,0,cntinpack-MOD(e_cnt_p,cntinpack)) Flt_Expr=IIF(m.tlWithNull,'','WHERE e_cnt#0 OR e_cnt_p#0') INSERT into rem_tg ; SELECT id , medname as name, retailprice as price ,e_cnt as cnt,e_cnt_p as cnt_p,cntinpack,barcode,app_tyme,date,inv_no ; FROM _rest &Flt_Expr &&WHERE e_cnt+e_cnt_p>0 USE IN _rest ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2004, 08:25 |
|
||
|
Увеличить скорость расчета остатков
|
|||
|---|---|---|---|
|
#18+
тихо сам с собою я веду беседу? С уважением duШes ....кто здесь?!!!!! ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2004, 08:57 |
|
||
|
Увеличить скорость расчета остатков
|
|||
|---|---|---|---|
|
#18+
Dushesтихо сам с собою я веду беседу? С уважением duШes ....кто здесь?!!!!! ;) Зачем же сам с собой ведешь беседу? Это уже нехороший признак :-)))) Вопрос звучал как (ведержки): 1. Как оптимизировать запрос, который отрабатывает долго? 2. Иной более оптимальный (по скорости выполнения) алгоритм? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2004, 09:00 |
|
||
|
Увеличить скорость расчета остатков
|
|||
|---|---|---|---|
|
#18+
Если уж ты спрашиваешь про запрос, то постарайся написать его в удобочитаемом виде. Это для тебя здесь все просто и понятно. Вот смотри, я просто переписал твой запрос в удобочитаемом виде: Код: 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. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. Кое-что, конечно, подправил. Но это косметические исправления. Несколько замечаний: -) В твоем изначальном коде WHERE d.closed ... AND d.closed - зачем 2 раза писать одно и то же условие. -) Крайне нежелатеьно для псевдонима таблицы использовать букву "m". В FoxPro под выражением типа "m.id" понимается прежде всего переменная памяти с именем "id" и только уже потом поле таблицы. Т.е. ты можешь нарваться на некорректную работу запроса -) Вместо IIF(IsNull(),...,...) можно использовать NVL(...,...) Результат тот же, но выражение короче -) Если ты используешь функции от строковых выражений (AllTrim()+...), то результат таких выражений надо явно добивать до фиксированного количества символов (PADR(AllTrim()+...,50)) чтобы поле в резуольтирующей выборке имело фиксированную размерность -) Использовать пустую строку как выражение поля ('' as inv_no) крайне неразумно. Надо указать явную размерность (SPACE(10) as inv_no) -) Я не совсем понял твой запрос, но мне непонятно, почему ты сделал UNION ALL вместо FROM receipts r ; LEFT JOIN expenses e ON r.id=e.rcpt_id ; Ты же это имел в виду, когда писал NOT IN ? -) Зачем ты тянешь имена из справочников непосредственно в запросе? Если реузльтирующая выборка будет относительно невелика, то разумнее имена "подтянуть" после выполнения основного запроса (2 последовательных запроса). Вообще, не пробовал разбивать твой один большой запрос на несколько подзапросов? -) Вообще-то, Select-SQL - это далеко не всегда самый быстрый способ пулучения выборки. Рассмотри вопрос прямого сканирования исходных таблиц и явного заполнения временной таблицы - результата выборки. Что-то вроде: Код: plaintext 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2004, 10:36 |
|
||
|
Увеличить скорость расчета остатков
|
|||
|---|---|---|---|
|
#18+
ВладимирМ Спасибо большое! Ваши ответы и рекомендации всегда отличаются четкость изложения и глубоким и многосторонним знанием проблемы. Данный запрос писал не я, а другой товарищ! Он так же сказал, что оптимизировал select до 3-х таблиц и не получил выигрыша в скорости. Говорит, проблема в том, что объемы таблиц очень большие, допустим таблица receipts = 30MB (приход) expenses = 40 Mb (расход) Я сейчас подумаю как scan спользовать или вот такой алгоритм: 1) С помощью select получить выборку по всему расходу сгруппированному по конкретным приходным позициям с сумированием соответ. полей e.rcpt_id 2) уст-ть связь receipts.id с expenses.rcpt_id 3)scan по receipts и expenses и вычитать и кидать в новую таблицу результат ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2004, 11:40 |
|
||
|
Увеличить скорость расчета остатков
|
|||
|---|---|---|---|
|
#18+
Так, кое-что проясняется. Попробуй сделать так: 1) Делаешь выборку ТОЛЬКО по приходам 2) Делаешь выборку ТОЛЬКО по расходам 3) Объединяешь первые 2 выборки (по LEFT JOIN) У тебя самые большие таблицы - это "приход" и "расход". В общем случае, объединение этих таблиц в одном запросе будет работать медленне, чем 2 отдельных запроса. Хотя, опять же, не факт. Это надо экспериметировать. Тебе поможет функция SYS(3054) для определения уровня оптимизации запроса. Будет понятно, какие индексы надо добавить. Хотя, SYS(3054) тоже далека от совершенства. Опять же, факт полной оптимизации вовсе не говорит о том, что запрос будет выполняться быстрее. Вполне может быть, что полная оптимизиация замедлит выполнение запроса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2004, 12:20 |
|
||
|
|

start [/forum/topic.php?fid=41&fpage=354&tid=1595545]: |
0ms |
get settings: |
7ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
25ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
34ms |
get tp. blocked users: |
1ms |
| others: | 212ms |
| total: | 308ms |

| 0 / 0 |
