2011-02-22 13 views
1

このInformix SQL文は、時間がかかります。誰もそれを最適化する方法を見ているので、あまり時間がかかりませんか?InformixでのSQL文のパフォーマンスの問題

SELECT * FROM OriginalTable WHERE type = 'S' AND flag <> 'S' INTO TEMP TempTableA; 

SELECT * FROM OriginalTable WHERE type = 'Z' AND flag <> 'S' INTO TEMP TempTableB; 

UPDATE OriginalTable SET flag = 'D' WHERE Serialnumber in 
(
select Serialnumber from TempTableA 
WHERE NOT EXISTS(SELECT * FROM TempTableB 
       WHERE TempTableB.Col1 = TempTableA.Col1 
       AND TempTableB.Col2 = TempTableA.Col2) 
) 

は、私は私のOriginalTableで約300万行、TempTableA 93K行、およびTempTableB 58K行を持っています。

+0

あなたは私が何のエントリが等しいのCol1とcol2 –

+0

の意図を説明する必要があります私は構文がinformix comatibleであるかどうかわかりません、私は構文に深刻な問題に直面しています。たとえば、テーブルのエイリアスは、 "どこ"の部分があるかのように、informixで期待どおりに機能しません。 joinと同じです。これは私に一時テーブルを使用させます。だから私はExcludeとしてこれらのExcludetheseを抽出するとき、私はまだ、OUTER WHEREの部分を持つ結合を実行することはできません。私はテーブルのエイリアスのための新しいスレッドを開こうとしますが、私はこのwouldntの助けになると思います。 – CloudyMarble

答えて

2
Update OriginalTable 
Set flag = 'D' 
Where Type = 'S' 
    And Flag <> 'S' 
    And Not Exists (
        Select 1 
        From OriginalTable As T1 
        Where T1.Type = 'Z' 
         And T1.flag <> 'S' 
         And T1.Col1 = OriginalTable.Col1 
         And T1.Col2 = OriginalTable.Col2 
        ) 
+0

私はあなたの答えを読んだ後、私は同じパフォーマンスの問題に直面していることを確信していたので、私はあなたの答えを読んだ後disapointed感じ今直面している!しかし、私はdidnt。それは甘く、本当に私が期待していたよりもはるかに優れています。どうもありがとうございました。 – CloudyMarble

+0

ちょうど情報として、テーブル/ビューをサブクエリーで使用することは不可能なので、結果をTempTableに再度保存し、別々のステップで変更する必要がありました。 – CloudyMarble

0

私は、テストデータでテストするのが面倒だったが、多分これは行うことができますか?

SELECT col1, col2, 
CASE WHEN type = 'S' THEN 1 
ELSE WHEN type = 'Z' THEN 2 END AS filteredType 
FROM OriginalTable WHERE (type = 'S' OR type = 'Z') AND flag <> 'S' INTO TempTable; 

UPDATE OriginalTable SET flag = 'D' WHERE Serialnumber IN 
(
SELECT t1.Serialnumber FROM TempTable t1 
LEFT JOIN TempTable t2 ON (t1.col1 = t2.col2 AND t1.col2 = t2.col2) 
WHERE t1.filteredType = 1 
AND t2.filteredType = 2 
AND t2.Serialnumber IS NULL 
) 

このようにして、一時表に1つの読み込みを省略することができます。一方、新しい列filteredTypeにはインデックスはありません。

また私はinformixのことを知らない。とにかくそれが助けてくれることを願います

0

@tombomと同様のアプローチで述べています。テンポラリテーブルを小さく保つために気にするカラムだけを事前にクエリします。あなたが60列のテーブルを扱っている場合、あなたの主な考慮事項が有効なシリアル番号である場合は、3〜4列以上のものをいっぱいにしています。クエリを事前テストして、期待している正しいセットが得られていることを確認してから、SQLアップデートに適用します。だからここ

、内側のクエリはあなたがこの表からのみの列1と列2と比較するたので、あなたは...したくないものです、それは私が事前に問い合わせをしていすべてです。次に、COL1とCOL2のこの内部結果セットにLEFT JOINを実行します。私は知っている、あなたはこの結果セットで見つけたものを除外したいと思っています...それで、OUTER WHERE句に「AND ExcludeThese.Col1 IS NULL」を追加しました。したがって、サブクエリに存在しなかったOT1のインスタンスは、(左結合を使用して)うまく行き、見つかったものはcol1とcol2に一致しますが、THOSEは「and」節で除外されます。説明されています。

SELECT OT1.SerialNumber 
    FROM OriginalTable OT1 
     LEFT JOIN (select OT2.Col1, 
          OT2.Col2 
         FROM OriginalTable OT2 
         where OT2.type = 'Z' 
         AND OT2.flag <> 'S') ExcludeThese 
      ON OT1.Col1 = ExcludeThese.Col1 
      AND OT1.Col2 = ExcludeThese.Col2 
    WHERE OT1.type = 'S' 
     AND OT1.flag <> 'S' 
     AND ExcludeThese.Col1 IS NULL 
    ORDER BY 
     OT1.SerialNumber 
    INTO 
     TEMP TempTableA; 

また、このクエリを単独でテストして、期待するレコードが得られていることを確認してください。こうした今

SELECT OT1.SerialNumber, 
     OT1.Col1, 
     OT1.Col2, 
     ExcludeThese.Col1 JoinedCol1, 
     ExcludeThese.Col2 JoinedCol2 
    from <keep rest of query intact> 

などの精神的/健全性チェックのために多くの列を含むように上記の選択を変更する、レコードを明確に返さ支援するために、あなたはそれらの列のシリアル番号とインスタンスを参照することができますことだろうまたは「excludeThese」結果セットに結合することがない...もう一度試してみてください、だけ を削除「AND ExcludeThese.Col1はNULL IS」句、あなたが他の線が表示されますし、それらが除外されている理由 - それは、次の場合ですあなたはそのコンテンツに疑問を持っていました。

事前クエリに満足すれば、一時テーブルに引っ張ってインデックスを作成し、更新を適用するため、インデックス/最適化できるSerialNumberの単一の列のみが返されます。

UPDATE OriginalTable 
    SET flag = 'D' 
    WHERE Serialnumber in (select Serialnumber from TempTableA ); 
+0

こんにちは、あなたの答えをありがとう、とTemptableBには存在しないためにOriginalTable内のすべてのセットのフラグを変更する必要があるクエリ – CloudyMarble

関連する問題