5

更新に非常に長い時間がかかる LEFT JOIN を含むマテリアライズド ビューが Oracle にあります。基になるテーブルを更新すると、実行に 63914.765 秒かかります (はい、ほぼ 17 時間です)。

データを行から列にピボットしたいので、同じテーブルで LEFT JOIN を使用しています。この Oracle バージョンではピボット コマンドを使用できません。FAST REFRESH マテリアライズド ビューでは、GROUP BY + CASE を使用できません。

マテリアライズド ビュー ログは次のようになります。

CREATE MATERIALIZED VIEW LOG ON Programmes_Titles
WITH PRIMARY KEY, rowid
INCLUDING NEW Values;

マテリアライズド ビュー自体は次のようになります (700000 行が含まれ、Programmes_Titles テーブルには 900000 行が含まれます)。

CREATE MATERIALIZED VIEW Mv_Web_Programmes
REFRESH FAST ON COMMIT 
AS

SELECT
    t1.ProgrammeId,        
    t1.Title as MainTitle,
    t2.Title as SecondaryTitle,
    --Primary key
    t1.Title_Id as t1_titleId,
    t2.Title_Id as t2_titleId,

    t1.rowid as t1_rowid,
    t2.rowid as t2_rowid
FROM
    Programmes_Titles t1, 
    Programmes_Titles t2
WHERE
    t1.Titles_Group_Type = 'mainTitle'
    AND t1.Programme_Id = t2.Programme_Id(+) AND t2.Titles_Group_Type(+) = 'secondaryTitle'

私が使用する UPDATE ステートメントは次のとおりです。

UPDATE Programmes_Titles 
SET Title = 'New title' 
WHERE rowid = 'AAAL4cAAEAAAftTABB'

この UPDATE ステートメントには 17 時間かかります。INNER JOIN ((+) を削除) を使用すると、数ミリ秒かかります。

また、Mv_Web_Programmes マテリアライズド ビューに INDEXES を追加しようとしましたが、それも役に立たないようです。(それはまだ 1 分以上実行されますが、これは遅い方法です。変更のたびに 17 時間待っているわけではないので、UPDATE が改善される可能性があります)

だから私の質問は: 基になるテーブルを更新するのになぜそんなに時間がかかるのですか? どうすればこれを改善できますか?

4

2 に答える 2

3

10.2.0.3 インスタンスで問題を再現できました。自己結合と外部結合が大きな問題のようです (ただし、MV のすべての列のインデックスでは、最終的に 1 分以内に更新されました)。

最初は、集約MVを使用できると思いました:

SQL> CREATE MATERIALIZED VIEW LOG ON Programmes_Titles
  2  WITH PRIMARY KEY, ROWID (programmeId, Titles_Group_Type, title)
  3  INCLUDING NEW Values;

Materialized view log created

SQL> CREATE MATERIALIZED VIEW Mv_Web_Programmes
  2  REFRESH FAST ON COMMIT
  3  AS
  4  SELECT ProgrammeId,
  5         MAX(decode(t1.Titles_Group_Type, 'mainTitle', t1.Title)) MainTl,
  6         MAX(decode(t1.Titles_Group_Type, 'secondaryTitle', t1.Title)) SecTl
  7    FROM Programmes_Titles t1
  8   GROUP BY ProgrammeId;

Materialized view created

残念ながら、お気付きのように、10gの時点で、MIN または MAX を含む MV は、挿入後のコミット時にのみ高速リフレッシュできます(いわゆる挿入のみの MV)。上記の解決策は、更新/削除には機能しません (MV を手動で更新する必要があります)。

セッションをトレースし、トレース ファイルを開いて実行される SQL クエリを確認し、インデックスを介して最適化できるかどうかを確認できます。

于 2011-11-21T11:24:24.937 に答える