Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

В какую сторону можно оптимизировать запрос?


Страницы:   1 2 3

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]

Я ещё тут ночью подумала :)))
Судя по терминам, упоминающимся в запросе, это что-то связанное с бухгалтерией, причем данные выбираются за несколько месяцев, то есть это, скорее всего, какой-то сводный отчет, получаемый после закрытия какого-либо периода (месяца,квартала и т.п.)
Возможно, есть смысл организовать некое подобие хранилища данных, то есть создать какую-либо таблицу (совокупность таблиц), которая будет использоваться для подобных отчетов, куда периодически заносить предварительно обработанные данные.
Или хотя бы вьюшки наделать, чтобы наглядность повысить :))


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо