4

私は現在、OFBizベースのERPの展開に取り組んでいます。使用されているデータベースはOracle10gEnterpriseです。

最大の問題の1つは、いくつかのOracleのパフォーマンスの問題であり、ofbizログの分析、次のクエリです。

SELECT DISTINCT ORDER_ID, ORDER_TYPE_ID, ORDER_NAME, EXTERNAL_ID,
 SALES_CHANNEL_ENUM_ID, ORDER_DATE, ENTRY_DATE, VISIT_ID, STATUS_ID, CREATED_BY, 
 FIRST_ATTEMPT_ORDER_ID, CURRENCY_UOM, SYNC_STATUS_ID, BILLING_ACCOUNT_ID, 
 ORIGIN_FACILITY_ID, WEB_SITE_ID, PRODUCT_STORE_ID, TERMINAL_ID, TRANSACTION_ID, 
 AUTO_ORDER_SHOPPING_LIST_ID, NEEDS_INVENTORY_ISSUANCE, IS_RUSH_ORDER, INTERNAL_CODE, 
 REMAINING_SUB_TOTAL, GRAND_TOTAL, LAST_UPDATED_STAMP, LAST_UPDATED_TX_STAMP, CREATED_STAMP, 
CREATED_TX_STAMP, RECIBIR_BODEGAL, RECEPCIONADA_BODEGAL, FECHA_RECEPCION_BODEGAL FROM 
ERP.ORDER_HEADER WHERE ((STATUS_ID = :v0 OR STATUS_ID = :v1 OR STATUS_ID = :v2) AND 
(ORDER_TYPE_ID = :v3)) ORDER BY ORDER_DATE DESC

とても遅いです。DISTINCTを使用せずにクエリを実行することをテストしましたが、約30秒かかります。テーブルには4.000.000以上のレジスタがあります。PKフィールドorderIdと他のほとんどすべてのフィールドのインデックスがあります

DISTINCTを使用したEXPLAINPLANは次のとおりです。

SELECT STATEMENT () (null)
 SORT (ORDER BY)    (null)
  HASH (UNIQUE) (null)
   TABLE ACCESS (FULL)  ORDER_HEADER

DISTINCTがない場合は次のとおりです。

SELECT STATEMENT () (null)
 SORT (ORDER BY)    (null)
  TABLE ACCESS (FULL)   ORDER_HEADER

この種のクエリのパフォーマンスを向上させるためにオラクルを調整することについて何かアイデアはありますか?ofbizによって自動的に生成されるため、クエリを書き直すのは非常に困難です。そのため、解決策はoracleの調整に関するものだと思います。

前もって感謝します

編集:Rob van Wijkとhaffaxによって提案されたように、tkprofを使用してクエリを分析したところ、結果は次のようになりました。

********************************************************************************

SELECT DISTINCT ORDER_ID, ORDER_TYPE_ID, ORDER_NAME, EXTERNAL_ID,
 SALES_CHANNEL_ENUM_ID, ORDER_DATE, ENTRY_DATE, VISIT_ID, STATUS_ID, CREATED_BY, 
 FIRST_ATTEMPT_ORDER_ID, CURRENCY_UOM, SYNC_STATUS_ID, BILLING_ACCOUNT_ID, 
 ORIGIN_FACILITY_ID, WEB_SITE_ID, PRODUCT_STORE_ID, TERMINAL_ID, TRANSACTION_ID, 
 AUTO_ORDER_SHOPPING_LIST_ID, NEEDS_INVENTORY_ISSUANCE, IS_RUSH_ORDER, INTERNAL_CODE, 
 REMAINING_SUB_TOTAL, GRAND_TOTAL, LAST_UPDATED_STAMP, LAST_UPDATED_TX_STAMP, CREATED_STAMP, 
CREATED_TX_STAMP, RECIBIR_BODEGAL, RECEPCIONADA_BODEGAL, FECHA_RECEPCION_BODEGAL FROM 
ERP.ORDER_HEADER WHERE STATUS_ID = 'ORDER_COMPLETED' ORDER BY ORDER_DATE DESC

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.03       0.01          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      9.10     160.81      66729      65203         37          50
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      9.14     160.83      66729      65203         37          50

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 58  

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       1        0.00          0.00
  db file scattered read                       8178        0.28        146.55
  direct path write temp                       2200        0.04          4.22
  direct path read temp                          36        0.14          2.01
  SQL*Net more data to client                     3        0.00          0.00
  SQL*Net message from client                     1        3.36          3.36
********************************************************************************

したがって、問題は「dbファイルの分散読み取り」であるように思われます。このイベントでの待機を減らすためにOracleを調整する方法についてのアイデアはありますか?

新しいtkprofの結果をフォローアップし、今回はセッションを閉じます。

********************************************************************************

SELECT DISTINCT ORDER_ID, ORDER_TYPE_ID, ORDER_NAME, EXTERNAL_ID,
 SALES_CHANNEL_ENUM_ID, ORDER_DATE, ENTRY_DATE, VISIT_ID, STATUS_ID, CREATED_BY,
 FIRST_ATTEMPT_ORDER_ID, CURRENCY_UOM, SYNC_STATUS_ID, BILLING_ACCOUNT_ID,
 ORIGIN_FACILITY_ID, WEB_SITE_ID, PRODUCT_STORE_ID, TERMINAL_ID, TRANSACTION_ID,
 AUTO_ORDER_SHOPPING_LIST_ID, NEEDS_INVENTORY_ISSUANCE, IS_RUSH_ORDER, INTERNAL_CODE,
 REMAINING_SUB_TOTAL, GRAND_TOTAL, LAST_UPDATED_STAMP, LAST_UPDATED_TX_STAMP, CREATED_STAMP,
CREATED_TX_STAMP, RECIBIR_BODEGAL, RECEPCIONADA_BODEGAL, FECHA_RECEPCION_BODEGAL FROM
ERP.ORDER_HEADER WHERE STATUS_ID = 'ORDER_COMPLETED' ORDER BY ORDER_DATE DESC

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.03       0.01          0          0          0           0
Execute      2      0.00       0.00          0          0          0           0
Fetch        1      8.23      47.66      66576      65203         31          50
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      8.26      47.68      66576      65203         31          50

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 58 

Rows     Row Source Operation
-------  ---------------------------------------------------
     50  SORT ORDER BY (cr=65203 pr=66576 pw=75025 time=47666679 us)
3456659   TABLE ACCESS FULL ORDER_HEADER (cr=65203 pr=65188 pw=0 time=20757300 us)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       1        0.00          0.00
  db file scattered read                       8179        0.14         34.96
  direct path write temp                       2230        0.00          3.91
  direct path read temp                          52        0.14          0.84
  SQL*Net more data to client                     3        0.00          0.00
  SQL*Net message from client                     1     1510.62       1510.62
********************************************************************************
4

6 に答える 6

3

ハッシュ集約を無効にしてみてください:

select /*+ no_use_hash_aggregation*/ distinct ...

http://oracle-randolf.blogspot.com/2011/01/hash-aggregation.html

于 2012-09-17T04:22:42.297 に答える
2

に従って結果を並べ替えてorder_dateいるため、そのフィールドに降順のインデックスがあることが重要です。また、この索引を使用することをオラクルに伝えます。フィールドをクエリの最初に配置し、order_date次のようなヒントを使用します

SELECT /*+ index(HEADERS IDX_ORDER_DATE_DESC) */ ... 
FROM ERP.ORDER_HEADER HEADERS
WHERE ...
ORDER BY ORDER_DATE DESC

インデックスを持つことではなく、オラクルにそれらを使用するように指示することです。オラクルはインデックスについて非常にうるさいです。最も重要なクエリに従ってインデックスを選択すると、最良の結果が得られます。疑問がある場合は、クエリをトレースします。このようにして、オラクルがクエリのどの部分で最も時間を費やしているか、およびインデックスが実際に取得されているかどうかを確認できます。トレースは、パフォーマンスの問題に対処する際に非常に役立ちます。

于 2009-06-26T23:19:47.037 に答える
1

2 つのクエリの違いが大きい場合、それは驚くべきことです。DISTINCT を使用しないクエリには約 30 秒かかるとのことです。DISTINCT を使用したクエリにはどのくらいの時間がかかりますか?

「alter session set events '10046 trace name context forever, level 8'」でセッションをトレースした後、DISTINCT を使用してクエリの tkprof 出力を表示し、クエリが終了した後に切断できますか? このようにして、実際に時間が費やされている場所と、何かを待っていたかどうかを確認できます (「ダイレクト パス読み取り温度」でしょうか?)

よろしく、ロブ。


TKPROFファイルが投稿された後、フォローアップ:

TKPROF出力を取得できたと思いますが、残念ながらTKPROFファイルを作成する前にセッションを切断しませんでした。これで、カーソルが開いたままになり、トレースファイルに統計#行を書き込むことができませんでした。

私の側からのちょっとした憶測: 非常に多くの列を選択しているため、DISTINCT はほとんどノーオペレーションだと思います。これが当てはまる場合、述語「WHERE STATUS_ID = 'ORDER_COMPLETED'」は非常に選択的であり、この列にインデックスを作成することでメリットが得られます。インデックスを作成したら、データ値が歪んでいる場合はヒストグラムをオンにして、適切に分析してください。最終結果は、INDEX RANGE SCAN で始まり、その後に TABLE ACCESS BY ROWID が続き、非常に高速なクエリにつながる、このクエリの別の計画になります。

インデックスを作成したら、次のステートメントを使用してヒストグラムを含め、テーブルを再分析できます。

exec dbms_stats.gather_table_stats([owner],[table_name],cascade=>true,method_opt=>'FOR ALL INDEXED COLUMNS SIZE')

よろしく、ロブ。

于 2009-06-27T22:55:42.040 に答える
-1

クエリを実行するたびに、Oracle はテーブル全体にアクセスしています ( TABLE ACCESS (FULL) )。STATUS_ID および ORDER_TYPE_ID 列での INDEX の作成

CREATE INDEX ERP.ORDER_HEADER_I1 ON ERP.ORDER_HEADER ( STATUS_ID, ORDER_TYPE_ID );

特に、ORDER_HEADER テーブルに STATUS_ID と ORDER_TYPE_ID の異なる値がいくつかある場合は、非常に役立ちます。

于 2009-06-27T18:16:43.383 に答える