2

私は次の3つのテーブルを持っています(実際にはもっと多くのフィールドがありますが、これは私が達成しようとしていることのアイデアを与えるはずです):

log (
  eventId INTEGER,
  objectId INTEGER,
  PRIMARY KEY (eventId)
)

objects (
  objectId INTEGER,
  typeId INTEGER,
  PRIMARY KEY (objectId, typeId)
)

statusBits (
  typeId INTEGER,
  bitNumber INTEGER,
)

このlogテーブルには非常に多くのレコード(500,000以上)が含まれていますが、他のテーブルは非常に小さいです。次のクエリを使用してテーブルを結合できます。

SELECT l.eventId, o.typeId, s.bitNumber
FROM log l, objects o, statusBits s
WHERE (l.objectId = o.objectId) AND (o.typeId = s.typeId)

このクエリは素晴らしく高速に実行されます。ORDER BY eventId最後に句を追加すると、高速に実行されます。ただし、追加するとORDER BY eventId, bitNumber(つまり、1つではなく2つのフィールドで並べ替える)、非常に遅くなります。

クエリを最適化して、実行速度を上げるにはどうすればよいですか?違いがあれば、Oracle10gXEを実行しています。

更新: 私はすでに試しましCREATE INDEX ON statusBits(bitNumber)たが、それは大きな効果がないようです。

4

1 に答える 1

0

まず、クエリを次のようにリファクタリングします。

SELECT L.eventId
    ,O.typeId
    ,S.bitNumber
FROM log L
INNER JOIN objects O ON O.objectId = L.objectId
INNER JOIN statusBits S ON S.typeId = O.typeId

おそらく実行時間には役立たないかもしれませんが、クエリははるかに読みやすく、 の使用がINNER JOINベスト プラクティスです。

次に、実行時間を最適化するために頭に浮かぶ最初の解決策はインデックスを作成することですが、それは既にテスト済みです。単純なインデックスの代わりに、連結されたインデックスを試すと役立つ場合があります。

CREATE INDEX ON statusBits (typeId, bitNumber);

これが役立つことを願っています。

于 2014-09-05T09:57:55.147 に答える