![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
В какую сторону можно оптимизировать запрос?
k2 © (2004-12-29 14:41:00)И вообще што неправильно(запрос рабочий, выдает правильные данные, но это первый запрос, с ораклом только начала работать, хотелось бы знать на што в первую очередь внимание обратить)
SELECT
CASE WHEN objs_name IS NULL AND GROUPING (cnt_class_modif) = 0 THEN 'Итого : ' ELSE inn END inn,
CASE WHEN GROUPING (cnt_class_modif) = 1 THEN 'Итого к строке баланса :' ELSE objs_name END objs_name,
SUM (sum_deb_zdl),
SUM (sum_deb_zdl_pr),
cnt_class_modif
FROM (SELECT cnt01.inn inn, objs_name,
NVL (sum_deb_val, 0) - NVL (sum_cred_val, 0) sum_deb_zdl,
NVL (sum_deb_val_pr, 0) - NVL (sum_cred_val_pr, 0) sum_deb_zdl_pr,
CASE
WHEN NVL (sum_deb_val, 0) - NVL (sum_cred_val, 0) < 1000 THEN 891 -- 891
WHEN NOT(cnt03cnt10.cnt10_id = 882 OR cnt03cnt10.cnt10_id = 883) THEN 890 -- 890
WHEN cnt03cnt10.cnt10_id IS NULL THEN 890 -- 890
ELSE cnt03cnt10.cnt10_id
END cnt_class_modif
FROM (SELECT val_set.objs_pk, val_set.objs_name,
val_set.objs_code,
SUM (CASE WHEN pr_type = 'deb' THEN val_int ELSE 0 END) sum_deb_val,
SUM (CASE WHEN pr_type = 'cr' THEN val_int ELSE 0 END) sum_cred_val,
SUM (CASE WHEN pr_type = 'deb' AND TRUNC (contr_posting_date) <= ADD_MONTHS (:end_date, -3) THEN val_int ELSE 0 END) sum_deb_val_pr,
SUM (CASE WHEN pr_type = 'cr' AND TRUNC (contr_posting_date) <= ADD_MONTHS (:end_date, -3) THEN val_int ELSE 0 END) sum_cred_val_pr,
MIN (contr_posting_date) min_posting_date
FROM (SELECT contr.val_int val_int, 'deb' pr_type,
contr.posting_date contr_posting_date,
objs.pk objs_pk, objs.NAME objs_name,
objs.code objs_code
FROM gl_contrecs contr,
gl_accounts acc,
gl_anlprops props,
gl_anlobjs objs
WHERE acc.pk = contr.acc_db_pk
AND acc.acpl_code = :acpl_code
AND acc.code LIKE :acc_code
AND contr.posted = :posted
AND contr.bu_code = :bu_code
AND props.crec_db_pk = contr.pk
AND objs.pk = props.anob_pk
AND objs.anca_code = :anca_code
AND TRUNC (contr.posting_date) <= :end_date
UNION ALL
SELECT contr.val_int val_int, 'cr' pr_type,
contr.posting_date contr_posting_date,
objs.pk objs_pk, objs.NAME objs_name,
objs.code objs_code
FROM gl_contrecs contr,
gl_accounts acc,
gl_anlprops props,
gl_anlobjs objs
WHERE acc.pk = contr.acc_cd_pk
AND acc.acpl_code = :acpl_code
AND acc.code LIKE :acc_code
AND contr.posted = :posted
AND contr.bu_code = :bu_code
AND props.crec_cd_pk = contr.pk
AND objs.pk = props.anob_pk
AND objs.anca_code = :anca_code
AND TRUNC (contr.posting_date) <= :end_date) val_set
GROUP BY objs_pk, objs_name, objs_code),
cnt_01_hoz_subjects cnt01,
cnt_cnt03_cnt10 cnt03cnt10,
cnt_03_contragents cnt03,
cnt_10_classes cnt10
WHERE NVL (sum_deb_val, 0) - NVL (sum_cred_val, 0) > 0
AND objs_code = cnt01.ID(+)
AND cnt03cnt10.cnt02_cnt01_id(+) = :balunit
AND cnt03cnt10.cnt01_id(+) = objs_code
AND cnt03.cnt01_id(+) = cnt01.ID
AND cnt03.cnt02_cnt01_id(+) = :balunit
AND cnt10.ID(+) = cnt03cnt10.cnt10_id)
GROUP BY
GROUPING SETS ((inn, objs_name, cnt_class_modif), ROLLUP (cnt_class_modif))
ORDER BY
cnt_class_modif, objs_name
Petr V. Abramov (2004-12-30 12:57:00) [1]> Мое ИМХО - подзапросы (в том же Оракле) и ХП (возвращающие НД)
> в ИБ - это практически одно и то-же. Я даже думаю, что часто в
> ИБ использование ХП - это просто способ обойти отсутствие
> подзапросов
И я, и я того же мнения
Sandman25 (2004-12-30 12:18:00) [2][48] k2 © (30.12.04 11:48)
AND (props.crec_cd_pk = contr.pk or props.crec_db_pk = contr.pk)
ну и изменить извлекаемые поля, конечно
Sandman25 (2004-12-30 12:15:00) [3][47] Sergey13 © (30.12.04 11:46)
Возможно. Но хотя бы читабельность останется.
k2 (2004-12-30 11:48:00) [4]Danilka © (30.12.04 11:35) [46]
если чесно больше всего мне не нравится union, ведь шерстятся одни и те же таблицы два раза с разницей в одно малюсенькое условие :( ..
Sergey13 (2004-12-30 11:46:00) [5]2[44] Sandman25 © (30.12.04 11:04)
Скорее всего оптимизатор все равно переделает на OR. ИМХО.
Danilka (2004-12-30 11:35:00) [6][45] k2 © (30.12.04 11:09)
разнесла на два разных поля val_int_deb и val_int_cr? Тогда сразу и SUM (val_int_deb - val_int_cr) sum_val стоит сделать по-моему.
k2 (2004-12-30 11:09:00) [7]Sandman25 © (30.12.04 11:04) [44]
спасибо, и от deb/cr избавилась
Sandman25 (2004-12-30 11:04:00) [8]cnt03cnt10.cnt10_id = 882 OR cnt03cnt10.cnt10_id = 883 можно заменить на
cnt03cnt10.cnt10_id in [882,883]
Danilka (2004-12-30 10:50:00) [9][42] k2 © (30.12.04 10:45)
Понятно, спасибо, буду теперь знать, а то у меня этих декодов много. :)
k2 (2004-12-30 10:45:00) [10]to Danilka © (30.12.04 10:29) [41]
в книжке Мишра/Бьюли "Секреты Oracle SQL" рекомендуют таки case использовать (у нас 9.2) "Выражения CASE выполняются быстрее чем DECODE. Так как case встроено в грамматику, нет необходимости в вызове функции для оценки логики if-then-else. Для одного вызова разница во времени исполнения будет мизерной, но при работе с большими множествами суммарная экономия времени на вызове функции станет значительной."
Danilka (2004-12-30 10:29:00) [11]Боюсь, что через какое-то время могут вылезти нехилые тормоза - ты рассчитываешь обороты на лету, с начала времен и по заданную дату. С каждым месяцем запрос все тяжелее и тяжелее будет отрабатываться.
На мой взгляд, самый лучший вариант сделать отдельную таблицу, в которой хранить обороты и сальдо за месяц. Например, у нас это сделано ввиде отдельной операции у клиента, кроме того, есть опарация "закрытие месяца", которая также ее пересчитывает, и больше за этот месяц никакие документы крячиться не могут. Чтобы что-то исправить - можно его заново открыть. Можно открыть только последний закрытый месяц, и закрыть только первый открытый. Все в бухгалтерии довольны и счастливы. :))
И еще, в Орокле вместо CASE можно использовать DECODE, на мой взгляд намного нагляднее и удобнее. :))
Sergey13 (2004-12-30 10:25:00) [12]Мое ИМХО - подзапросы (в том же Оракле) и ХП (возвращающие НД) в ИБ - это практически одно и то-же. Я даже думаю, что часто в ИБ использование ХП - это просто способ обойти отсутствие подзапросов. Вот вроде в ФБ2 обещают поддержку подзапросов, к чему бы это?
Кроме того сами по себе много мелких запросов не всегда дают нужный результат - их результаты надо еще объединить - а это уже интересная (как минимум) задача.
Хотя конечно в каждом конкретном случае - конкретное решение.
Johnmen (2004-12-30 10:16:00) [13]>Sandman25 © (30.12.04 10:10) [38]
Вот-вот, и я про это...
Sandman25 (2004-12-30 10:10:00) [14][37] Johnmen © (30.12.04 10:05)
Вот именно, всё зависит от запросов. В одном случае произошло огромное ускорение при разбивке большого запроса из ХП на несколько отдельных запросов (помещенных к тому же в отдельные ХП), в другом - пришлось переделать ХП в обратном направлении, задействовав запросы на несколько страниц.
Johnmen (2004-12-30 10:05:00) [15]>Sergey13 © (30.12.04 10:01) [36]
Конечно, может уделать. И так же может, что нет.
Sergey13 (2004-12-30 10:01:00) [16]2[35] Johnmen © (30.12.04 09:57)
>Разница, если в ХП неск.мелких легких запросов. Вместо одно монстроидального...
Так ить иногда суммарный вес мелких помноженый на "оптимальный" код в ХП может с лихвой уделать и не одного монстра. 8-)
Johnmen (2004-12-30 09:57:00) [17]>Sergey13 © (30.12.04 09:40) [34]
>А какая разница при использовании ХП и того же кода/логики в
>запросе? Разве что компиляция при выполнении.
Разница, если в ХП неск.мелких легких запросов. Вместо одно монстроидального...
Sergey13 (2004-12-30 09:40:00) [18]2[25] k2 © (29.12.04 18:33)
>таблицы не очень большие,
Тогда фул скан не особо страшен. Хотя определение "не очень большие" расплывчатое слегка. Кому и мульен записей - фигня. 8-)
>статистика второй день собирается,
Это уже лучше. Но я бы попробовал еще с хинтом RULE. Иногда СВО бывает уж шибко вумным. 8-)
>заметила, што пару раз вместо...
Это и правда интересно. Может оптимизатор меняли на RULE.
>два фулскана на самом нижнем уровне вложения
Возможно это LIKE делает
2[29] Thick (29.12.04 22:41)
>Фиговые у тебя запросы!
>Во первых нах так загружать сеть такими запросами???
Где тут нагрузка на сеть, не подскажешь?
2[30] Fay © (29.12.04 22:57)
>Мне иногда помогал хинт FIRST_ROWS
В чем помогал?
2[31] Johnmen © (29.12.04 23:36)
>Как зачем? снизить нагрузку, однако....
А мне не раз удавалось повысить производительность запроса на порядки именно используя вложенные запросы.
>>> или эти мелкие запросы использовать в хранимой процедуре.
>> Все это верно для IB/FB
>Это верно для всех SQL серверов
А какая разница при использовании ХП и того же кода/логики в запросе? Разве что компиляция при выполнении.
233] k2 © (30.12.04 07:15)
>отчет квартальный, пользователей немного
Тогда, учитывая что "запрос рабочий, выдает правильные данные", вообще все зашибись. 8-)
k2 (2004-12-30 07:15:00) [19]to Наталия © (30.12.04 06:29) [32]
:) Наташ надеюсь кошмары не снились :) а то я себе не прощу :)
отчет квартальный, пользователей немного, я думала што вьюшки используются наоборот - при частом обращении, и к тому же пока не очень хотелось бы плодить новые объекты, база итак очень большая (хотя ей конешно с моей одной таблички ни жарко ни холодно не будет :)), разработчиков было несколько, постоянно натыкаюсь на какието таблицы-связки, вобщем пока более-менее осматриваюсь
Наталия (2004-12-30 06:29:00) [20]Я ещё тут ночью подумала :)))
Судя по терминам, упоминающимся в запросе, это что-то связанное с бухгалтерией, причем данные выбираются за несколько месяцев, то есть это, скорее всего, какой-то сводный отчет, получаемый после закрытия какого-либо периода (месяца,квартала и т.п.)
Возможно, есть смысл организовать некое подобие хранилища данных, то есть создать какую-либо таблицу (совокупность таблиц), которая будет использоваться для подобных отчетов, куда периодически заносить предварительно обработанные данные.
Или хотя бы вьюшки наделать, чтобы наглядность повысить :))