2

以下のSQLのパフォーマンスを向上させるために誰かが私を助けることができますか?使用するデータベースはinformixです

SELECT 
   informix.set_reason_codes.description as reason_code, 
   count(*) as number_of_calls
FROM 
informix.contact_history,
informix.set_reason_codes,
informix.customers
WHERE 
  (informix.contact_history.reason_code = informix.set_reason_codes.reason_code)
and ( ( informix.set_reason_codes.code_type = 'CONTACT_HISTORY' ) )
and ( informix.contact_history.customerkey = informix.customers.customerkey ) 
and ( informix.contact_history.call_type = 0 ) 
group 
   by informix.set_reason_codes.description  
order by 
   informix.set_reason_codes.description  
4

2 に答える 2

3

EXPLAIN ON を指定してこの SQL を実行して、クエリ プランを取得する必要があります。

SET EXPLAIN ON;
SELECT ....

これにより、オプティマイザーの計画がファイルに書き込まれます (実際の場所は、OS と接続方法によって異なります)。

これを取得すると、パフォーマンスの問題の原因を特定するのにはるかに適した立場になります。しかし、通常は、次のいずれかになります。

  • 不適切なインデックス
  • インデックス統計が古いか欠落している

NESTED LOOP (インデックス結合) が予想される AUTO-INDEX または SEQUENTIAL SCAN に関する sqexplain ファイル内のメッセージは、チューニングが必要なかなり良い指標です。他に何もない場合は、クエリを実行して説明出力を取得し、実行します。

UPDATE STATISTICS MEDIUM FOR TABLE informix.contact_history;
UPDATE STATISTICS MEDIUM FOR TABLE informix.set_reason_codes;
UPDATE STATISTICS MEDIUM FOR TABLE informix.customers;

パフォーマンスで劇的に異なる結果が得られ、クエリ プランで報告された場合、問題が統計に関連していることがわかります。

実行している Informix のバージョンも知っておくと便利です。

于 2009-09-25T08:28:39.263 に答える
2

テーブルエイリアスを使用してSQLを読み取り可能にする方法を学びます。

SELECT r.description AS reason_code, COUNT(*) AS number_of_calls
  FROM informix.contact_history  AS h,
       informix.set_reason_codes AS r,
       informix.customers        AS c
 WHERE h.reason_code = r.reason_code
   AND r.code_type   = 'CONTACT_HISTORY' 
   AND h.customerkey = c.customerkey 
   AND h.call_type   = 0 
 GROUP BY r.description  
 ORDER BY r.description

余分なブラケットを避けることも役立ちます。レイアウトについて議論することはできますが、これらの線に沿ったものは通常、合理的に見えます。

別の日、テーブルの所有者としてユーザー「informix」を使用することのメリットまたはメリットの欠如について議論することができます-そうしないことをお勧めしますが、それが彼らにとって最良の選択であると主張する人もいます。(私は彼らの推論に同意しませんが、顧客は常に正しいです。)

パフォーマンスに関しては、コメントでインデックスは次のようになっています。

  • contact_historyの場合、customerkey、date_and_time、reason_codeの1つのインデックス。
  • set_reason_codesの場合、code_type、reason_codeの1つのインデックス
  • 顧客の場合、customerkeyの1つのインデックス

あなたの問題の一部はここにあります。あなたはおそらくインデックスから利益を得るでしょう:

CREATE INDEX fk_contact_history ON contact_history(reason_code);

これは、''の結合に役立ちh.reason_code = r.reason_codeます。既存のインデックスは、それをまったく使用しません。

インデックスの恩恵を受けるかもしれません:

CREATE INDEX ix_set_reason_codes ON set_reason_codes(reason_code);

次に、問題の核心にたどり着きます。あなたはcustomerテーブルに参加しますが、実際にそうする理由はないようです-がcustomerkey実際にテーブルの主キーであると仮定しcustomersます。

したがって、このクエリから同じ結果が得られます。

SELECT r.description AS reason_code, COUNT(*) AS number_of_calls
  FROM informix.contact_history  AS h,
       informix.set_reason_codes AS r
 WHERE h.reason_code = r.reason_code
   AND r.code_type   = 'CONTACT_HISTORY' 
   AND h.call_type   = 0 
 GROUP BY r.description  
 ORDER BY r.description
于 2009-09-27T02:38:41.837 に答える