0

我有大约 53 个代码字符串的查询,我需要对其进行优化。我有 PL/SQL Developer 7.0 工具,我应该如何使用它进行优化?

我尝试使用解释计划,但它什么也没告诉我。我还添加了时间和时间戳列,但没有什么有趣的,第一个是空的,第二个总是相同的时间。

我尝试使用测试窗口,但有一个过程需要变量插入,并且当我的查询选择许多行时,我无法使用它。

所以问题是如何使用 PL/SQL Developer 优化 sql 查询?我应该在哪里寻找每个子查询的查询执行时间?也许有一些指南,但现在我只找到了文档,但它对我没有用?就我目前的知识而言,如果没有任何工具,似乎不可能优化如此大的查询。

查询,需要优化:

select count(PRODUCT_NUMBER)
  from 
(select W.SUID,
       I.SUID,
       W.PRODUCT_NUMBER,
       MI.ML_NUMBER,
       I.TITLE_TRANSLIT,
       I.COUNTRIES,
       QTY.REMAINS,
       QTY.ACQ_PRICE_USD,
       QTY.REMAINS * QTY.ACQ_PRICE_USD as TOTAL
  from (select UID_WARE,
               QTY as REMAINS,
               ACQ_PRICE_USD
          from (select UID_WARE,
                       PRODUCT_NUMBER,
                       NVL(sum(QTY_ON_STOCK), 0) - NVL(sum(ADD_IN_QTY), 0) + NVL(sum(ADD_OUT_QTY), 0) as QTY,
                       ACQ_PRICE_USD as ACQ_PRICE_USD
                  from (select SI.UID_WARE,
                               W.PRODUCT_NUMBER,
                               count(distinct STK.SUID) as QTY_ON_STOCK,
                               sum(case
                                     when 1 = 1  then
                                      DECODE('' , SM.UID_SOURCE_LOCATION, SM.QTY, 0)
                                     else 0
                                   end) as ADD_OUT_QTY,
                               sum(case
                                     when 1 = 1  then
                                      DECODE('' , SM.UID_DEST_LOCATION, SM.QTY, 0)
                                     else 0
                                   end) as ADD_IN_QTY,
                               ROUND(ACQ.PRICE_USD, 2) as ACQ_PRICE_USD
                          from STOCK_MOVEMENTS SM
                          join STOCK_ITEMS SI on SM.UID_STOCK_ITEM = SI.SUID
                          left outer join (select PR.UID_STOCK_ITEM,
                                                 DECODE(NVL(CR.RATE, 0), 0, 0, PR.PRICE / CR.RATE) as PRICE_USD
                                            from MV_STOCK_ACQ_PRICES PR,
                                                 CURRENCY_RATES CR
                                           where PR.PRICE_DATE = CR.RATE_DATE
                                                 and PR.UID_CURRENCY = CR.UID_CURRENCY) ACQ on ACQ.UID_STOCK_ITEM = SI.SUID
                          join WARES W on W.SUID = SI.UID_WARE
                          left outer join (select distinct STK.SUID,
                                                           STK.QTY_REMAINS
                                             from STOCK_ITEMS STK
                                            where STK.UID_STOCK_LOCATION != 'MS-STL-SALED' 
                                                  ) STK on STK.SUID = SI.SUID
                         where 1 = 1

                         group by SI.UID_WARE,
                                  W.PRODUCT_NUMBER,
                                  ACQ.PRICE_USD
                        ) T
                 group by T.UID_WARE,
                          T.PRODUCT_NUMBER,
                          ACQ_PRICE_USD)) QTY
  join WARES W on W.SUID = QTY.UID_WARE
  join INVENTORY I on I.SUID = W.UID_ISSUE
  join MAP_INFO MI on MI.SUID = I.SUID
 where REMAINS != 0
       and w.UID_SECTION in ('MS-SEC-BOOKS', 'MS-SEC-MAPS'))
4

2 回答 2

1

当您使用 GUI 分析和优化查询时,您将自己锁定在一个小得多的潜在帮助社区中。如果您运行解释计划并使用 DBMS_XPlan.Display 来获取格式化的结果,那么您正在使用一种被成千上万的从业者理解的标准方法。

另外,我怀疑您已将查询包装在仅使用 count(*) 的外部查询中。虽然这可能是运行查询而无需返回所有行,但您很可能会得到一个完全不同的执行计划,尽管有一些提示可能有助于促进使用通常的计划,但不能保证它会成功。 t 改变。所以,如果这是为了调优方便,就把它拿走。

所以我的建议:

  1. 以常规的基于查询的方式运行解释计划,不要依赖“帮助”的工具。
  2. 运行您需要调整的实际查询。
  3. 发布执行计划。
于 2012-12-19T10:50:47.507 回答
0

对于执行时间,从这里

SQL> set timing on;

在 PL/SQL Developer 中,您可以独立运行每个子查询——用鼠标标记它并按F8。您将在 sql 窗口的左下角(在结果下方)看到执行时间。

优化不是一件容易的事,您必须自己思考 - 据我所知,没有工具可以为您做到这一点。您的方法可能取决于许多因素 - 数据库版本、底层操作系统、表大小、索引...

您可以阅读一些指南(例如thisthisthis

更新

根据您的数据库版本,您可以尝试使用CTESQL 建模- 它们肯定会提高性能,但需要一些时间来学习。

代替group by,您可以尝试分析函数(例如partition by,请参阅此链接以获取示例)。

于 2012-12-19T10:06:27.973 回答