oracleはparallelのせいだ

13127 ワード

このプロジェクトは中国聯通xxxx通話システムで、私のアーキテクチャ設計+需要設計、+運行維持保障+データベース開発、サービスセットです.
今日開発が終わった後、突然モジュールの需要があって、ユーザー番号は選択しなければならなくて、少し憂鬱な感じがして、1時間に1000 wのデータがあるため、すべてのユーザー番号を表示して、少し蛇を描いて足を添えるのではないでしょうか.
私の最初の構想は、明細書を照会することです.中移営業庁のように、番号を入力する必要があります.あるいは、省の証明書があいまいな照会を照会する必要があります.述語がなければ照会できません.(デザインが合理的だと感じた)
1.しかし、システム全体のユーザー分布を理解するには、条件を入力する必要があります.少し使用できないのではないでしょうか.
2.述語フィルタがなく、クエリーが遅く、非常に遅く(1-2分で結果が出る)、3-5秒以内にデータが出ることを目標としています.
注:最適化の難点は2秒を1秒にすることです.逆に、2時間を2分にするのは簡単です.
ステップ1:
文と実行計画を見てみましょう.
SQL>  explain plan for  SELECT /*+ parallel(8)   */
  2   starttime starttime,
  3   cv.groupid,
  4   cs.custmangerid,
  5   callercarrier callercarrier,
  6   callernum callernum,
  7   calledcarrier calledcarrier,
  8   callednum callednum,
  9   calleenum calleenum,
 10   round(duration / 60, 2) CallTimeLen,
 11   count(*) over(ORDER BY NULL ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) "@totalrows"
 12    FROM CS_xxxx dt, cfg_vipphones cv, cfg_vipusers cs
 13   WHERE dt.StartTime >= '2013-05-31 13:00:00'
 14     and dt.StartTime < '2013-05-31 14:00:00'
 15     AND dt.Callercarrier = 2
 16     AND dt.callernum >= cv.beginphone
 17     and dt.callernum <= cv.endphone
 18     and cv.groupid = cs.groupid;
 
Explained
 
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2172492340
--------------------------------------------------------------------------------
| Id  | Operation                              | Name            | Rows  | Bytes
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                 |   478K|    34
|*  1 |  PX COORDINATOR                        |                 |       |
|   2 |   PX SEND QC (RANDOM)                  | :TQ10001        |   478K|    34
|   3 |    WINDOW BUFFER                       |                 |   478K|    34
|*  4 |     FILTER                             |                 |       |
|   5 |      MERGE JOIN                        |                 |   478K|    34
|   6 |       SORT JOIN                        |                 |    11 |   363
|   7 |        BUFFER SORT                     |                 |       |
|   8 |         PX RECEIVE                     |                 |       |
|   9 |          PX SEND BROADCAST             | :TQ10000        |       |
|  10 |           NESTED LOOPS                 |                 |       |
|  11 |            NESTED LOOPS                |                 |    11 |   363
|  12 |             TABLE ACCESS BY INDEX ROWID| CFG_VIPUSERS    |     3 |    18
|  13 |              INDEX FULL SCAN           | PK_CFG_VIPUSERS |     3 |
|* 14 |             INDEX RANGE SCAN           | VIPUSERS_FK     |     4 |
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
|  15 |            TABLE ACCESS BY INDEX ROWID | CFG_VIPPHONES   |     4 |   108
|* 16 |       FILTER                           |                 |       |
|* 17 |        SORT JOIN                       |                 |   516K|    21
|  18 |         PX BLOCK ITERATOR              |                 |   516K|    21
|* 19 |          TABLE ACCESS FULL             | CS_xxxx          |   516K|    21
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(TO_DATE('2013-05-31 13:00:00')<TO_DATE('2013-05-31 14:00:00'))
   4 - filter(TO_DATE('2013-05-31 13:00:00')<TO_DATE('2013-05-31 14:00:00'))
  14 - access("CV"."GROUPID"="CS"."GROUPID")
  16 - filter("DT"."CALLERNUM"<="CV"."ENDPHONE")
  17 - access("DT"."CALLERNUM">="CV"."BEGINPHONE")
       filter("DT"."CALLERNUM">="CV"."BEGINPHONE")
  19 - filter("DT"."CALLERCARRIER"=2 AND "DT"."STARTTIME">='2013-05-31 13:00:00'
Note
-----
   - Degree of Parallelism is 8 because of hint
 
41 rows selected
 
SQL> 
皆さんは問題を見ましたか.正直に言うと、実行計画はただの参考です.indexが有効かどうかを見てみましょう.全表scan、nloop、hashではありませんか.useを増やすことができますか.nl,等hint
OLAPとOLT Pはまた大きな違いがあり、データベースパラメータ設定、sql書き方、hintが有効かどうかなどが含まれています.
ステップ2:
3枚のテーブル関連で述語に問題があったのではないかと疑っています.
filterを見て、パーティションテーブルがやったのかどうかを見てください.私が書いたので、私が一番よく知っています.ははは...
マルチテーブル関連付けの場合、ビューがある場合は、ビューのマージ、関連付けの優先選択を考慮してhashすることができます.全部やってみたが、だめだ.
ステップ3:
パラレルエラーの疑いがあります.テーブルの並列度を見て、インデックスの並列を見てください.
あるいは並行してやってみないでください.やはり、8-10秒で結果が出ます
SQL>  explain plan for  SELECT
  2   starttime starttime,
  3   cv.groupid,
  4   cs.custmangerid,
  5   callercarrier callercarrier,
  6   callernum callernum,
  7   calledcarrier calledcarrier,
  8   callednum callednum,
  9   calleenum calleenum,
 10   round(duration / 60, 2) CallTimeLen,
 11   count(*) over(ORDER BY NULL ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) "@totalrows"
 12    FROM CS——xx dt, cxg_vippxxx cv, cxg_vipxxx cs
 13   WHERE dt.StartTime >= '2013-05-31 13:00:00'
 14     and dt.StartTime < '2013-05-31 14:00:00'
 15     AND dt.Callercarrier = 2
 16     AND dt.callernum >= cv.beginphone
 17     and dt.callernum <= cv.endphone
 18     and cv.groupid = cs.groupid;
 
Explained
 
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1705527799
--------------------------------------------------------------------------------
| Id  | Operation                         | Name            | Rows  | Bytes |Tem
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                 |   478K|    34M|
|   1 |  WINDOW BUFFER                    |                 |   478K|    34M|
|*  2 |   FILTER                          |                 |       |       |
|   3 |    MERGE JOIN                     |                 |   478K|    34M|
|   4 |     SORT JOIN                     |                 |    11 |   363 |
|   5 |      NESTED LOOPS                 |                 |       |       |
|   6 |       NESTED LOOPS                |                 |    11 |   363 |
|   7 |        TABLE ACCESS BY INDEX ROWID| CFGxxUSERS    |     3 |    18 |
|   8 |         INDEX FULL SCAN           | PK_CFG_VIPUSERS |     3 |       |
|*  9 |        INDEX RANGE SCAN           | VIPUSERS_FK     |     4 |       |
|  10 |       TABLE ACCESS BY INDEX ROWID | CFG_xxNES   |     4 |   108 |
|* 11 |     FILTER                        |                 |       |       |
|* 12 |      SORT JOIN                    |                 |   516K|    21M|
|  13 |       PARTITION RANGE ITERATOR    |                 |   516K|    21M|
|* 14 |        TABLE ACCESS FULL          | CS_xxx         |   516K|    21M|
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(TO_DATE('2013-05-31 13:00:00')<TO_DATE('2013-05-31 14:00:00'))
   9 - access("CV"."GROUPID"="CS"."GROUPID")
  11 - filter("DT"."CALLERNUM"<="CV"."ENDPHONE")
  12 - access("DT"."CALLERNUM">="CV"."BEGINPHONE")
       filter("DT"."CALLERNUM">="CV"."BEGINPHONE")
  14 - filter("DT"."CALLERCARRIER"=2 AND "DT"."STARTTIME">='2013-05-31 13:00:00'
              14:00:00')
 
32 rows selected
 
SQL> 

ステップ4:
パラレル設定を見てみると、これも大きな関係があります.パラレルモジュールが多すぎて、列が混雑している場合があります.
<1>システムの最大並列数よりも並列度が低いクエリが走っている場合、次の並列クエリはどのように走りますか?When you specify parallel degree 4 oracle tries to allocate 4 producer slaves and 4 consumer slaves. The producers can feed any of the consumers.  If there are only 2 slaves available then we use these.  If there is only 1 slave available then we go serial  If there are none available then we use serial.  If parallel_min_percent is set then we error ora 12827 instead of using a lower number of slaves or going serial<2>parallel_を設定max_serversはいくつですか.マルチCPUの環境では、CPU-1またはCPUの数を最大並列数とするのが一般的である、パラレルクエリの実行時に各並列プロセスを調整するプロセスが1つ必要となるためである.単一CPUについては何も言うことはありません.<3>パラレルクエリはシステムのパフォーマンスを向上させることができますか?パラレルクエリの実行時には、マシンを高負荷で実行することが容易であり、他のトランザクションに対するシステムの処理時間を大幅に長くすることができる.パラレルクエリは一般的に非業務のピーク時に手動で実行するのに適しており、プログラムでパラレルクエリの実行を指定するのに適していない.PINNER:パラレルは高速ではなく、データ・ウェアハウス環境、低トラフィック・リクエストと低パラレル・オペレーションに適した典型的なOLTPシステムであり、私たちのシステムであれば、パラレル・クエリーは絶対に許されません. 
(推薦ハ)
ステップ5:
問題解決、問題点に注意して、paralleの書き方を見て、1つのテーブルの時、parallel(8)を使って、現在のテーブルの並列の8つのプロセスを表します
複数のテーブルがある場合は、テーブルを指定してください.そうしないと、3つのテーブルがデフォルトになります.もちろん、実行計画では見えません.traceしてみてください.
SQL>  explain plan for  SELECT /*+ parallel(dt,8)   */
  2   starttime starttime,
  3   cv.groupid,
  4   cs.custmangerid,
  5   callercarrier callercarrier,
  6   callernum callernum,
  7   calledcarrier calledcarrier,
  8   callednum callednum,
  9   calleenum calleenum,
 10   round(duration / 60, 2) CallTimeLen,
 11   count(*) over(ORDER BY NULL ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) "@totalrows"
 12    FROM CS_CDR dt, cfg_vipphones cv, cfg_vipusers cs
 13   WHERE dt.StartTime >= '2013-05-31 13:00:00'
 14     and dt.StartTime < '2013-05-31 14:00:00'
 15     AND dt.Callercarrier = 2
 16     AND dt.callernum >= cv.beginphone
 17     and dt.callernum <= cv.endphone
 18     and cv.groupid = cs.groupid;
 
Explained
 
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2172492340
--------------------------------------------------------------------------------
| Id  | Operation                              | Name            | Rows  | Bytes
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                 |   478K|    34
|*  1 |  PX COORDINATOR                        |                 |       |
|   2 |   PX SEND QC (RANDOM)                  | :TQ10001        |   478K|    34
|   3 |    WINDOW BUFFER                       |                 |   478K|    34
|*  4 |     FILTER                             |                 |       |
|   5 |      MERGE JOIN                        |                 |   478K|    34
|   6 |       SORT JOIN                        |                 |    11 |   363
|   7 |        BUFFER SORT                     |                 |       |
|   8 |         PX RECEIVE                     |                 |       |
|   9 |          PX SEND BROADCAST             | :TQ10000        |       |
|  10 |           NESTED LOOPS                 |                 |       |
|  11 |            NESTED LOOPS                |                 |    11 |   363
|  12 |             TABLE ACCESS BY INDEX ROWID| CFG_VIPUSERS    |     3 |    18
|  13 |              INDEX FULL SCAN           | PK_CFG_VIPUSERS |     3 |
|* 14 |             INDEX RANGE SCAN           | VIPUSERS_FK     |     4 |
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
|  15 |            TABLE ACCESS BY INDEX ROWID | CFG_VIPPHONES   |     4 |   108
|* 16 |       FILTER                           |                 |       |
|* 17 |        SORT JOIN                       |                 |   516K|    21
|  18 |         PX BLOCK ITERATOR              |                 |   516K|    21
|* 19 |          TABLE ACCESS FULL             | CS_xxxx         |   516K|    21
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(TO_DATE('2013-05-31 13:00:00')<TO_DATE('2013-05-31 14:00:00'))
   4 - filter(TO_DATE('2013-05-31 13:00:00')<TO_DATE('2013-05-31 14:00:00'))
  14 - access("CV"."GROUPID"="CS"."GROUPID")
  16 - filter("DT"."CALLERNUM"<="CV"."ENDPHONE")
  17 - access("DT"."CALLERNUM">="CV"."BEGINPHONE")
       filter("DT"."CALLERNUM">="CV"."BEGINPHONE")
  19 - filter("DT"."CALLERCARRIER"=2 AND "DT"."STARTTIME">='2013-05-31 13:00:00'
 
37 rows selected
 
SQL> 

現在は3秒で結果が出ており,述語が1時間であるか,番号フィルタリングがあるかは絶対に1秒以内の応答速度であると予想されている.