2

Teradata QA 環境で、1 分未満で実行された単純なクエリが完了するまでに 12 分かかるという問題に直面しています。この選択は、単純な内部結合に基づいて 5 つのフィールドをプルしています

select a.material
    , b.season
    , b.theme
    , b.collection
from SalesOrders_view.Allocation_Deliveries_cur a
inner join SalesOrders_view.Material_Attributes_cur b
    on a.material = b.material;

これと同じクエリを Prod 環境で実行すると、QA よりも約 20 万件多くのレコードを実行しながら、1 分もかからずに結果が返されます。

合計ボリュームは、SalesOrders.Allocation_Deliveries で 110 万レコード未満、SalesOrders.Material_Attributes で 129,000 レコード未満です。これらは小さなデータセットです。

両方の環境で Explain プランを比較したところ、最初の Join ステップで推定スプール ボリュームに大きな違いがありました。本番環境での見積もりは期待どおりですが、QA での見積もりは桁違いです。ただし、データとテーブル/ビューは両方のシステムで同一であり、考えられるあらゆる方法で統計を収集しており、両方のシステムで特定のテーブルの人口統計が同一であることを確認できます。

最後に、このクエリは、QA を含むすべての環境で常に 1 分以内に返されます。この潜在的な行動は、先週かそこらで最近のものです。これについて DBA と話し合ったところ、ソフトウェアや構成に変更はありませんでした。彼は新人ですが、自分が何をしているかを知っているように見えますが、まだ新しい環境に追いついています.

次に何を確認するかについての指針を探しています。関連するテーブル/ビューの定義を QA と Prod で比較しましたが、それらは同一です。各システムのテーブルの人口統計も同じです(確認するためにDBAと一緒にこれらを調べました)

どんな助けでも大歓迎です。前もって感謝します。パット

これは QA からの Explain プランです。ステップ 5 の非常に低い見積もり (144 行) に注意してください。Prod では、同じ Explain が > 1 M 行を示しており、これは私が知っているものに近いものです。

Explain select a.material
    , b.season
    , b.theme
    , b.collection
from SalesOrders_view.Allocation_Deliveries a
inner join SalesOrders_view.Material_Attributes_cur b
    on a.material = b.material;

  1) First, we lock SalesOrders.Allocation_Deliveries in view
     SalesOrders_view.Allocation_Deliveries for access, and we lock
     SalesOrders.Material_Attributes in view SalesOrders_view.Material_Attributes_cur for
     access. 
  2) Next, we do an all-AMPs SUM step to aggregate from
     SalesOrders.Material_Attributes in view SalesOrders_view.Material_Attributes_cur by way
     of an all-rows scan with no residual conditions
     , grouping by field1 ( SalesOrders.Material_Attributes.material
     ,SalesOrders.Material_Attributes.season ,SalesOrders.Material_Attributes.theme
     ,SalesOrders.Material_Attributes.theme ,SalesOrders.Material_Attributes.af_grdval
     ,SalesOrders.Material_Attributes.af_stcat
     ,SalesOrders.Material_Attributes.Material_Attributes_SRC_SYS_NM).  Aggregate
     Intermediate Results are computed locally, then placed in Spool 4. 
     The size of Spool 4 is estimated with high confidence to be
     129,144 rows (41,713,512 bytes).  The estimated time for this step
     is 0.06 seconds. 
  3) We execute the following steps in parallel. 
       1) We do an all-AMPs RETRIEVE step from Spool 4 (Last Use) by
          way of an all-rows scan into Spool 2 (all_amps), which is
          redistributed by the hash code of (
          SalesOrders.Material_Attributes.Field_9,
          SalesOrders.Material_Attributes.Material_Attributes_SRC_SYS_NM,
          SalesOrders.Material_Attributes.Field_7, SalesOrders.Material_Attributes.Field_6,
          SalesOrders.Material_Attributes.theme, SalesOrders.Material_Attributes.theme,
          SalesOrders.Material_Attributes.season, SalesOrders.Material_Attributes.material)
          to all AMPs.  Then we do a SORT to order Spool 2 by row hash
          and the sort key in spool field1 eliminating duplicate rows. 
          The size of Spool 2 is estimated with low confidence to be
          129,144 rows (23,504,208 bytes).  The estimated time for this
          step is 0.11 seconds. 
       2) We do an all-AMPs RETRIEVE step from SalesOrders.Material_Attributes in
          view SalesOrders_view.Material_Attributes_cur by way of an all-rows scan
          with no residual conditions locking for access into Spool 6
          (all_amps), which is redistributed by the hash code of (
          SalesOrders.Material_Attributes.material, SalesOrders.Material_Attributes.season,
          SalesOrders.Material_Attributes.theme, SalesOrders.Material_Attributes.theme,
          SalesOrders.Material_Attributes.Material_Attributes_SRC_SYS_NM,
          SalesOrders.Material_Attributes.Material_Attributes_UPD_TS, (CASE WHEN (NOT
          (SalesOrders.Material_Attributes.af_stcat IS NULL )) THEN
          (SalesOrders.Material_Attributes.af_stcat) ELSE ('') END )(VARCHAR(16),
          CHARACTER SET UNICODE, NOT CASESPECIFIC), (CASE WHEN (NOT
          (SalesOrders.Material_Attributes.af_grdval IS NULL )) THEN
          (SalesOrders.Material_Attributes.af_grdval) ELSE ('') END )(VARCHAR(8),
          CHARACTER SET UNICODE, NOT CASESPECIFIC)) to all AMPs.  Then
          we do a SORT to order Spool 6 by row hash.  The size of Spool
          6 is estimated with high confidence to be 129,144 rows (
          13,430,976 bytes).  The estimated time for this step is 0.08
          seconds. 
  4) We do an all-AMPs RETRIEVE step from Spool 2 (Last Use) by way of
     an all-rows scan into Spool 7 (all_amps), which is built locally
     on the AMPs.  Then we do a SORT to order Spool 7 by the hash code
     of (SalesOrders.Material_Attributes.material, SalesOrders.Material_Attributes.season,
     SalesOrders.Material_Attributes.theme, SalesOrders.Material_Attributes.theme,
     SalesOrders.Material_Attributes.Field_6, SalesOrders.Material_Attributes.Field_7,
     SalesOrders.Material_Attributes.Material_Attributes_SRC_SYS_NM,
     SalesOrders.Material_Attributes.Field_9).  The size of Spool 7 is estimated
     with low confidence to be 129,144 rows (13,301,832 bytes).  The
     estimated time for this step is 0.05 seconds. 
  5) We do an all-AMPs JOIN step from Spool 6 (Last Use) by way of an
     all-rows scan, which is joined to Spool 7 (Last Use) by way of an
     all-rows scan.  Spool 6 and Spool 7 are joined using an inclusion
     merge join, with a join condition of ("(material = material) AND
     ((season = season) AND ((theme = theme) AND ((theme =
     theme) AND (((( CASE WHEN (NOT (af_grdval IS NULL )) THEN
     (af_grdval) ELSE ('') END ))= Field_6) AND (((( CASE WHEN (NOT
     (AF_STCAT IS NULL )) THEN (AF_STCAT) ELSE ('') END ))= Field_7)
     AND ((Material_Attributes_SRC_SYS_NM = Material_Attributes_SRC_SYS_NM) AND
     (Material_Attributes_UPD_TS = Field_9 )))))))").  The result goes into Spool
     8 (all_amps), which is duplicated on all AMPs.  The size of Spool
     8 is estimated with low confidence to be 144 rows (5,616 bytes). 
     The estimated time for this step is 0.04 seconds. 
  6) We do an all-AMPs JOIN step from Spool 8 (Last Use) by way of an
     all-rows scan, which is joined to SalesOrders.Allocation_Deliveries in view
     SalesOrders_view.Allocation_Deliveries by way of an all-rows scan with no
     residual conditions.  Spool 8 and SalesOrders.Allocation_Deliveries are
     joined using a single partition hash_ join, with a join condition
     of ("SalesOrders.Allocation_Deliveries.material = material").  The result goes
     into Spool 1 (group_amps), which is built locally on the AMPs. 
     The size of Spool 1 is estimated with low confidence to be 3,858
     rows (146,604 bytes).  The estimated time for this step is 0.44
     seconds. 
  7) Finally, we send out an END TRANSACTION step to all AMPs involved
     in processing the request.
  -> The contents of Spool 1 are sent back to the user as the result of
     statement 1.  The total estimated time is 0.70 seconds.

レコードの分布と、結果セットを生成するために使用した SQL は次のとおりです。

SELECT HASHAMP(HASHBUCKET(HASHROW( MATERIAL ))) AS
"AMP#",COUNT(*)
FROM EDW_LND_SAP_VIEW.EMDMMU01_CUR
GROUP BY 1
ORDER BY 2 DESC;

出力 最高: 1093 行の AMP 137 最低: 768 行の AMP 72 合計 AMP: 144

4

1 に答える 1

2

統計に関する推奨事項

PROD と QA で次を実行し、相違点を投稿します (必要に応じて列名を隠します)。

DIAGNOSTIC HELPSTATS ON FOR SESSION;

EXPLAIN
select a.material
    , b.season
    , b.theme
    , b.collection
from SalesOrders_view.Allocation_Deliveries_cur a
inner join SalesOrders_view.Material_Attributes_cur b
    on a.material = b.material;

この診断を EXPLAIN コマンドと組み合わせて実行すると、最適化プログラムが最小コストのクエリ プランを作成するのに役立つ推奨統計のリストが生成されます。これにより違いが生じない場合もあれば、環境 (データまたはその他) 間で何かが異なることを示している場合もあります。

ビューと JOIN 条件

EXPLAIN プランに基づいて、SalesOrders_View データベースのビューの 1 つまたは両方が EXISTS 句を使用しているようです。この EXISTS 句は、COALESCE 条件 (または明示的な CASE ロジック) に依存して、NOT NULL として定義されているあるテーブルの列と、NULL 値を許可するように定義されている別のテーブルの列との比較に対応しています。これは、その結合のパフォーマンスに影響を与える可能性があります。

データ配信

配布結果は PRODUCTION 環境のもののようです。(AMPS の数と、AMP に表示される最大行と最小行の行数に基づいています。) QA にとってはどのように見えますか?

編集 - 2013-01-09 09:21

データが 2 か月前に Prod からコピーされた場合、質問するのはばかげているように思えるかもしれませんが、統計は後で再収集されましたか? 置き換えられたデータの上にある古い統計は、環境間のクエリ プランの相違につながる可能性があります。

PPI テーブルでなくても、テーブルの PARTITION 統計を収集していますか? これは、オプティマイザがカーディナリティを見積もるのに役立ちます。

QA システムで実行されている唯一のワークロードですか?

DBQL メトリクスを調べて、各環境でのクエリの CPU と IO の消費を比較しましたか? IO スキュー、CPU スキュー、および不要な IO メトリックも見てください。

ワークロードを遅らせている可能性のある QA 環境に、遅延スロットルがありますか? これにより、実際の CPU 消費量と IO 消費量が QA と PROD で同じであるにもかかわらず、QA 環境での実行に時間がかかっていることがわかります。

ビューポイントにアクセスできますか?

その場合、My Queries または Query Spotlight ポートレットを使用してクエリを調べ、その動作を観察しましたか?

クエリ プランのどのステップが最もコストがかかり、時間がかかるか知っていますか? Viewpoint 前述のポートレットまたは DBQL のステップ ロギングのいずれかを使用して巻き戻すと、これを確認できます。

環境間の DBS コントロール設定は同じですか? DBA にこれを確認するよう依頼してください。そこには、オプティマイザが使用する結合計画に影響を与える可能性のある設定があります。

最終的に、ハードウェアと TDBMS パッチ レベルが同じ 2 つのシステムでデータ、テーブル構造、インデックス、および統計が同じである場合、2 つの異なる EXPLAIN プランを取得することはできません。その場合は、GSC に連絡して関与してもらうことをお勧めします。

于 2013-01-08T23:50:25.820 に答える