DISTINCT SELECTを使用してOracleでのパフォーマンスを向上させる方法

StackOverflow https://stackoverflow.com/questions/1051593

  •  20-08-2019
  •  | 
  •  

質問

私は現在、OFBizベースのERPの導入に取り組んでいます 使用されているデータベースは、Oracle 10グラムエンタープライズです。

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

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フィールド注文IDのインデックスとほぼすべての他のフィールドがあります。

DISTINCTとEXPLAIN PLANは、次のとおりです。

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

クエリのこの種のパフォーマンスを改善するには、Oracleのチューニングの任意のアイデア? それは自動的にofbizによって生成されるため、問合せをリライトすることは非常に困難です 私は解決策がチューニングオラクルについてだと思います。

事前のおかげで。

編集:ロブ・バン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ファイル」に任意のアイデアであると思われるので、どのようにこのイベントでの待機を低減するためにチューン神託をする?

新しい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
********************************************************************************
役に立ちましたか?

解決

2つのクエリ間の差は相当なものである場合は、

、それは驚くべきことだろう。あなたは、DISTINCTのないクエリは約30秒かかりますことを言及します。 DISTINCTを持つクエリがかかりますどのくらいの時間?

あなたは「『永遠10046トレース名コンテキストレベル8』セッションセットイベントを変更する」、およびクエリが完了した後に切断するとのセッションをトレースした後、

あなたは、DISTINCTを使用してクエリのTKPROF出力を表示することができますか?時間は実際に費やされている場合、それが何かを待っていたならば、私たちが見ることができるこの方法(多分、「ダイレクト・パス読みTEMP」?)

よろしく、 ロブます。

<時間>

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

私はあなたがTKPROF出力を得ることができたが、残念ながらあなたはTKPROFファイルを作成する前に、あなたのセッションを切断していない参照してください。今、カーソルが開いたままにして、それがあなたのトレースファイルにSTATの#行を書き込むことができませんでした。あなたはTKPROFファイル内の計画/行ソースの操作を持っていないのはこのためです。提案は以下のゴミであることが判明した場合は、プロセスを繰り返すことができた場合、それはいいだろう。

私の側から少し憶測:私はあなたが非常に多くの列を選択しているので、DISTINCTはほとんど何もしませんだと思います。これが本当であれば、「STATUS_IDは 『ORDER_COMPLETED』 =」あなたの述語は、非常に選択的であり、あなたはこの列に索引を持つの恩恵を受ける。あなたは、インデックスを作成した後、多分データ値が偏っている場合のヒストグラムで、あなたはそれを正しく分析することを確認してください。最終的な結果は非常に高速クエリにつながる、ROWID BY表ACCESS続いて、索引レンジ・スキャンで始まる、このクエリに対して異なる計画であろう。

あなたは、インデックスを作成した後、あなたがテーブルの再解析し、この文を使用してヒストグラムを含むを持つことができます:

EXEC DBMS_STATS.GATHER_TABLE_STATS( 'ALLインデックス列サイズの' [所有者]、[テーブル名]、カスケード=> trueを、METHOD_OPT =>)

よろしく、 ロブます。

他のヒント

あなたはあなたがそのフィールドに降順索引を持つことが重要であるorder_dateに応じて結果を注文しているので。 また、あなたは、このインデックスを使用したい神託を告げます。クエリで最初<=>フィールドを配置などのヒントを使用する

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

これは、インデックスを持っていることについてはあまりなく、むしろそれらを使用するには、Oracleを伝える話ではありません。 Oracleは、インデックスについて非常にうるさいです。あなたの最も重要なクエリに基づいてインデックスを選択したときに、最良の結果を得ます。疑問がある場合は、。この方法は、あなたが最も時間を費やしているクエリオラクルのどの部分で、あなたのインデックスが実際にピックアップされているか否かを確認することができます。パフォーマンスの問題を戦ったときにトレースは非常に貴重である。

ORDER_IDは、PRIMARY KEY制約を使用してPKとして宣言されていますか?それがある場合ので、私は、オプティマイザは、DISTINCTは、このクエリでは不必要であることを認識し、それを最適化することが期待されます。制約がなければ、それは不必要で知ることができませんので、「デデュープ」で結果を不要にし、かなりの労力を費やすだろう。

私はDBMS_SQLTUNEパッケージは、多くの時間を節約することがわかりSQLの制御を持っていないアプリケーションのトラブルシューティングを行う場合。 http://download.oracle.com/docsを参照してください。 /cd/B28359_01/appdev.111/b28419/d_sqltun.htm に、はい、残念ながらあなたはそれを使用するためのライセンスを取得する必要があります。

共有プールまたはAWRのリポジトリ内の特定のSQL_IDに対するチューニング分析を実行するには、このパッケージのプロシージャがあります。追加の索引で作られているいずれかの改善点があるかどうかの分析は、インデックスの勧告が含まれています。さらに重要なのは、アナライザは、OracleがSQLプロファイルと呼んで実装することができる改良アクセスパスを発見するかもしれない - これは、このSQL_IDが実行されるたびに保存され、使用されるヒントのセットです。これは、SQL文で符号化するヒントを必要とせずに発生し、アプリケーションが代わりにバインド変数の文でリテラル値を生成した場合、あなたはファジーマッチングを考えることができます何をするオプションもあります。

もちろん、このツールは、アプリケーションを理解するための代替すべきではない、それはデータ構造だが、(もし見つかれば)、より良い計画の実行パスの詳細を出力通読することは、教育することができます。

Oracleは、テーブル全体にクエリ(表アクセス(FULL))を実行するたびにアクセスしています。 STATUS_IDとORDER_TYPE_ID列に索引を作成する

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

ORDER_HEADERテーブルのSTATUS_IDとORDER_TYPE_IDのいくつかの異なる値がある場合は特に、多くのことを助けます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top