2017-11-21 9 views
1

非常に遅いです:呼ばテーブルは約300万行が含まれている場合のOracle副問合せのSELECT MAX()は、次のSQL

SELECT * 
FROM Transaction_Auth_Series t 
WHERE t.Auth_ID = 
(
    SELECT MAX(p.Session_ID) 
    FROM Clone_Db_Derective p 
    WHERE p.Date = trunc(sysdate) 
    AND p.Regularity = 'THEME' 
); 

は非常に遅いです。しかし、それはSQLは、2つのカーソルに書き込まれている場合、数秒の問題だすなわち

CURSOR GetMaxValue IS 
    SELECT MAX(p.Session_ID) 
     FROM Clone_Db_Derective p 
     WHERE p.Date = trunc(sysdate) 
     AND p.Regularity = 'THEME' 

    CURSOR GetAllItems(temp VARCHAR2) IS 
    SELECT * 
    FROM Transaction_Auth_Series t 
    WHERE t.Auth_ID = temp; 

........ 
    FOR item in GETMAX LOOP 
    FOR itemx in GETITEMS(item.aaa) LOOP....... 

テーブルが関連していないと機能しません参加します。上記のメインSQLをどうやって最適化できますか?このクエリの

+0

実行計画が最適ではない可能性があります。たとえば、オプティマイザは、おそらくテーブル統計に基づいて結合を最初に実行するように内部的に変換しました。そうであれば、統計を修正したり、クエリを並べ替えたりヒントしたりすることができます。 –

+0

あなたは@WilliamRobertsonの提案を詳しく教えてもらえますか? – MaDi

+0

このような単純なクエリに対して実行計画が悪い場合は、通常は統計が間違っていることを意味します。したがって、SQLチューニングの練習には、プランをチェックし、統計を確認する必要があります。彼らはどのように見えるのですか? –

答えて

0

SELECT t.* 
FROM Transaction_Auth_Series t 
WHERE t.Auth_ID = (SELECT MAX(p.Session_ID) 
        FROM Clone_Db_Derective p 
        WHERE p.Date = trunc(sysdate) AND p.Regularity = 'THEME' 
       ); 

私はClone_Db_Derective(Regularity, Date, Session_ID)Transaction_Auth_Series(Auth_Id)のインデックスをお勧めします。

(テーブルがビューではないと仮定して)このクエリの最適化は非常に簡単です。私は、カーソルのバージョンが非常に高速であることに驚いています。 WITHクエリの結果は、1つの平均値は2回または3回と比較する必要がある場合など、メインクエリの本体に複数回要求される場合句WITH

+0

はい、カーソルバージョンは必要なデータを数秒で取得します。ただし、Transaction_Auth_Seriesはビューであり、Clone_Db_Derectiveは索引付けされています。 – MaDi

+0

@ MaDi。 。 。ビューは、オプティマイザを混乱させる可能性があります。サブクエリを 'FROM'節に移動し、' JOIN'を使用してみてください。 –

+0

提案していただきありがとうございますが、結合はそれを助けるものではありません。これらは関連していないので、確かに助けにならないでしょうか? – MaDi

0
WITH max_session 
    AS (SELECT MAX (p.Session_ID) id 
      FROM Clone_Db_Derective p 
      WHERE p.Date = TRUNC (SYSDATE) AND p.Regularity = 'THEME') 
SELECT * 
    FROM Transaction_Auth_Series t 
WHERE t.Auth_ID = (SELECT id FROM max_session) 

Aは、最も価値があります。ポイントは、1回のクエリに複数回結合されたテーブルへのアクセス回数を最小限に抑えることです。

+0

私はWITHを試みましたが、成功しませんでした。それでも多くの時間がかかります(CURSORオプションは約2秒しかかかりませんが、約160秒です)。 – MaDi

+0

しかし、OPの全体的なクエリでサブクエリが1回だけ使用されるということです。このケースでは、オプティマイザがクエリ(この解答では)をOPの元のクエリに変換するため、WITH節がどのように変更されるかわかりません。 – mathguy

関連する問題