2016-11-24 6 views
0

私は比較的新しいSQLです。私は非常に迅速に実行する(< 0.5秒)が、1つの変更を追加すると非常にゆっくり(> 120秒)実行されたスクリプトがあります - そして、なぜこの変更がそのような違いをもたらすのか分かりません。どんな助けでも大いに感謝します!小さな変更でSQLスクリプトが非常に遅く実行される

これはスクリプトであると私はライン26で「tt2.bulk_cnt 」を含めない場合、それはすぐに実行されます。

with bulksum1 as 
(
select t1.membercode, 
     t1.schemecode, 
     t1.transdate 
from mina_raw2 t1 
where t1.transactiontype in ('RSP','SP','UNTV','ASTR','CN','TVIN','UCON','TRAS') 
group by t1.membercode, 
      t1.schemecode, 
      t1.transdate 
), 

bulksum2 as 
(
select t1.schemecode, 
     t1.transdate, 
     count(*) as bulk_cnt 
from bulksum1 t1 
group by t1.schemecode, 
      t1.transdate 
having count(*) >= 10 
), 

results as 
(
select t1.*, tt2.bulk_cnt 
from mina_raw2 t1 
inner join bulksum2 tt2 
on t1.schemecode = tt2.schemecode and t1.transdate = tt2.transdate 
where t1.transactiontype in ('RSP','SP','UNTV','ASTR','CN','TVIN','UCON','TRAS') 
) 

select * from results 

編集:私は以前ここに十分な詳細を入れないために謝罪 - 私はできますが基本的なSQLコードを使用して、私はデータベースについては完全な初心者です。

データベース:オラクル(私はわからないんだけどごめんバージョン、)

実行計画:

QUICKクエリ:

Plan hash value: 1712123489 

--------------------------------------------- 
| Id | Operation    | Name  | 
--------------------------------------------- 
| 0 | SELECT STATEMENT  |   | 
| 1 | HASH JOIN    |   | 
| 2 | VIEW     |   | 
| 3 | FILTER    |   | 
| 4 |  HASH GROUP BY  |   | 
| 5 |  VIEW    | VM_NWVW_0 | 
| 6 |  HASH GROUP BY  |   | 
| 7 |  TABLE ACCESS FULL| MINA_RAW2 | 
| 8 | TABLE ACCESS FULL  | MINA_RAW2 | 
--------------------------------------------- 

SLOWクエリ:

Plan hash value: 1298175315 

-------------------------------------------- 
| Id | Operation    | Name  | 
-------------------------------------------- 
| 0 | SELECT STATEMENT  |   | 
| 1 | FILTER    |   | 
| 2 | HASH GROUP BY  |   | 
| 3 | HASH JOIN   |   | 
| 4 |  VIEW    | VM_NWVW_0 | 
| 5 |  HASH GROUP BY  |   | 
| 6 |  TABLE ACCESS FULL| MINA_RAW2 | 
| 7 |  TABLE ACCESS FULL | MINA_RAW2 | 
-------------------------------------------- 
+0

どのデータベースプラットフォームですか? – OldProgrammer

+1

インデックスフィールドに参加していますか? –

+2

2つのクエリの実行計画を比較しましたか? – CodeReaper

答えて

0

いくつか観察し、次に行うべきことがあります。

1)詳細が必要です。特に、MINA_RAW2テーブルには何行あり、このテーブルにはどのインデックスが存在し、最後に分析されたのですか?これらの質問に対する答えを判断するには、次のコマンドを実行します

SELECT COUNT(*) FROM MINA_RAW2; 

SELECT TABLE_NAME, LAST_ANALYZED, NUM_ROWS 
    FROM USER_TABLES 
    WHERE TABLE_NAME = 'MINA_RAW2'; 

データベースはMINA_RAW2上の2回のFULLスキャンをやっているように見える計画出力を見てから - これは1個以下に減らすことができれば、それはいいだろう、そしてうまくいけば誰も。テーブルのデータに関する詳細な情報がなくても、それは常に難しいですが、最初はTRANSACTIONTYPEのインデックスが役立つかもしれません。そのようなインデックスが存在しない場合は、追加することを検討してください。

2)統計情報が古くなっている(古い、存在しない、または大量のデータ(> 10%)が最後の分析以降に追加、削除、または更新された場合など)次のようになります。

"YOUR-SCHEMA-NAME"に正しいスキーマ名を置き換えます。スキーマ名を大文字にすることを忘れないでください!統計を収集すべきかどうかわからない場合は、慎重に誤って実行してください。それは多くの時間を取るべきではありません。

3)テーブル統計を更新した後、既存のクエリを再試行してください。私は、データベースに最新の統計を持たせることであなたの問題を解決できることは間違いありません。そうでない場合:

4)このクエリは、GROUP BYの結果に対してGROUP BYを実行しています。最初のGROUP BYはグループ化を行わないため、これは必要ではないように思われます。代わりに、MEMBERCODE、SCHEMECODE、およびTRANSDATEの固有の組み合わせを取得するために行われているように見えます。日付を決定することができる。私は全体のクエリを簡素化することができると思います:

WITH cteWORKING_TRANS AS (SELECT * 
          FROM MINA_RAW2 
          WHERE TRANSACTIONTYPE IN ('RSP','SP','UNTV', 
                 'ASTR','CN','TVIN', 
                 'UCON','TRAS')), 
    cteBULKSUM AS (SELECT a.SCHEMECODE, 
          a.TRANSDATE, 
          COUNT(*) AS BULK_CNT 
         FROM (SELECT DISTINCT MEMBERCODE, 
              SCHEMECODE, 
              TRANSDATE 
           FROM cteWORKING_TRANS) a 
         GROUP BY a.SCHEMECODE, 
           a.TRANSDATE) 
SELECT t.*, b.BULK_CNT 
    FROM cteWORKING_TRANS t 
    INNER JOIN cteBULKSUM b 
    ON b.SCHEMECODE = t.SCHEMECODE AND 
     b.TRANSDATE = t.TRANSDATE 
+0

テーブルを分析すると、トリッククエリが非常に迅速に実行されるように見えました。また、あなたの修正されたクエリははるかに理にかなっています。あなたの助けをありがとう - それは非常に感謝しています! – Nick

0

I不要なサブクエリを削除することができましたが、この構文はdistinctcountはPostgreSQLの外部では動作しないかもしれませんし、望ましい結果にならないかもしれません。私は確かにそこにそれを使用したことを知っています。

select t1.*, tt2.bulk_cnt 
from mina_raw2 t1 
inner join (select t2.schemecode, 
     t2.transdate, 
     count(DISTINCT membercode) as bulk_cnt 
from mina_raw2 t2 
where t2.transactiontype in ('RSP','SP','UNTV','ASTR','CN','TVIN','UCON','TRAS') 
group by t2.schemecode, 
      t2.transdate 
having count(DISTINCT membercode) >= 10) tt2 
on t1.schemecode = tt2.schemecode and t1.transdate = tt2.transdate 
where t1.transactiontype in ('RSP','SP','UNTV','ASTR','CN','TVIN','UCON','TRAS') 

あなたがそれらのwithクエリを使用し

、代わりにあなたは、あなたがクエリオプティマイザをkneecappingしている必要はありませんサブクエリの。

+0

これはありがとうございます(確かに私の試みよりもはるかに良く見えます)。 – Nick

関連する問題