0

私は実行に長い時間がかかる次のSQLを持っていますが、速度を向上させるためにこれを書くためのより良い方法はありますか?

どんな助けでも非常に高く評価されます。

ありがとう

    SELECT a.KeyField
    FROM Details a,
         Master b
    WHERE a.ForeignKeyField = b.ForeignKeyField
      AND a.KeyField IS NOT NULL
      AND Date BETWEEN 
TO_DATE ('01-01-2011', 'dd-mm-yyyy') AND TO_DATE ('31-12-2011', 'dd-mm-yyyy')
      AND a.KeyField IN
        (SELECT p.KeyField
         FROM Details p,
              Master q
         WHERE q.ForeignKeyField = p.ForeignKeyField
           AND p.KeyField IS NOT NULL
           AND p.KeyField = a.KeyField
           AND q.FKField2 = b.FKField2
         GROUP BY p.KeyField,
                  q.Date HAVING COUNT (DISTINCT q.ForeignKeyField) > 1)
    GROUP BY b.Id,
             b.Name,
             b.ForeignKeyField,
             b.Date,
             a.ForeignKeyField,
             a.SomeOtherField,
             a.KeyField,
             b.EtcEtc
4

4 に答える 4

1

まず、適切な結合構文を学ぶ必要があります。私の推測では、相関サブクエリのために、Oracleは次善のクエリパスを選択しています。代わりに、結合に変更してみましょう。

SELECT a.KeyField
FROM Details a join
 Master b
 on a.ForeignKeyField = b.ForeignKeyField join
 (SELECT p.KeyField, q.Date, q.FKField2
  FROM Details p join
       Master q
       on q.ForeignKeyField = p.ForeignKeyField
  WHERE p.KeyField IS NOT NULL AND
        q.FKField2 = b.FKField2
  GROUP BY p.KeyField, q.Date
  HAVING COUNT (DISTINCT q.ForeignKeyField) > 1
 ) t
 on a.KeyField = t.KeyField and
    b.FKField2 = t.FKField2
WHERE a.KeyField IS NOT NULL AND
  Date BETWEEN TO_DATE ('01-01-2011', 'dd-mm-yyyy') AND TO_DATE ('31-12-2011', 'dd-mm-yyyy') AND
GROUP BY b.Id, b.Name, b.ForeignKeyField, b.Date, a.ForeignKeyField, a.SomeOtherField, a.KeyField, 
     b.EtcEtc

このように書くと、サブクエリで使用されますが、日付に条件がないこともわかります。これは正しいです?

于 2012-05-29T19:03:57.977 に答える
1

クエリでを実行するEXPLAINと、速度の低下がどこから来ているかがわかります。ただし、一般に、ネストされたクエリ(INステートメント)を回避できDISTINCT、クエリのパフォーマンスが向上する場合。Details同じクエリ内でテーブルとテーブルを2回結合することで解決できるかどうかを確認し、Masterそれに応じてインデックスを配置します

于 2012-05-29T18:58:24.463 に答える
0

関連するインデックスが設定されていることを確認してください。実行プランをチェックして、実際に使用されていることを確認します。オラクルは、インデックスの選択に関しては非常に慎重です。

于 2012-05-29T18:56:47.543 に答える
0

内部クエリの理由がわかりません。私はこのように単純化します:

SELECT a.KeyField
FROM Details a,
     Master b
WHERE a.ForeignKeyField = b.ForeignKeyField
  AND a.KeyField IS NOT NULL
  AND Date >= TO_DATE ('01-01-2011', 'dd-mm-yyyy')
  AND Date <= TO_DATE ('31-12-2011', 'dd-mm-yyyy')

GROUP BY b.Id,
         b.Name,
         b.ForeignKeyField,
         b.Date,
         a.ForeignKeyField,
         a.SomeOtherField,
         a.KeyField,
         b.EtcEtc
HAVING COUNT (DISTINCT q.ForeignKeyField) > 1

また、に置き換える BETWEEN>=, <=役立ちます

于 2012-05-29T18:58:52.720 に答える