これは私を約4時間悩ませているので、何か助けを求める時だと思った。私は類似したオンラインのものは何も見つかりませんが、主に値が非常に特殊で、何を探すべきかわからないからです...クエリーが変更された後でも、Oracleクエリーが同じ場所にスタックされる
これは私がOracleスクリプトで実行している問題ですSQLPlus 10.2.0.5。
問題:
:(名前と実際のデータは、容疑者の身元を保護するために変更されました) は、私は少しのようになりMONKEYSと呼ばれるテーブルとMONKEY_PUZZLESというテーブルを、持っています
MONKEYS
- MONKEY_ID
- GIRAFFE_ID
- MONKEY_PUZZLE_ID
MONKEY_PUZZLES
- MONKEY_PUZZLE_ID
- GIRAFFE_ID
MONKEY_PUZZLES.GIRAFFE_IDとMONKEYS.GIRAFFE_ID一致が、N MONKEY_PUZZLEあたりサル(SO MONKEY_PUZZLES.GIRAFFE_ID 1が一致する可能性がありますされていますMONKEY.MONKEY_ID 1、2、および334)。
MONKEY_PUZZLES.MONKEY_PUZZLE_IDフィールドに基づいてMONKEYS.MONKEY_PUZZLE_IDフィールドを設定したいのは、現在MONKEYS.MONKEY_PUZZLE_IDフィールドがnullであるためです。
- MONKEYS.MONKEY_ID(インデックスを持つ主キー)
- MONKEYS.GIRAFFE_ID
- MONKEY_PUZZLES.MONKEY_PUZZLE_ID(インデックスを持つ主キー)
- MONKEY_PUZZLES.GIRAFFE_ID
:私は上のインデックスを持っていますまた、MONKEYSテーブルには160万以上の行があり、MONKEY_PUZZLESテーブルには50,000以上の行があります。
私はもともと次のクエリを使用していた:
UPDATE MONKEYS M SET M.MONKEY_PUZZLE_ID =
(SELECT MP.MONKEY_PUZZLE_ID FROM MONKEY_PUZZLES MP
WHERE M.GIRAFFE_ID = MP.GIRAFFE_ID
AND MP.GIRAFFE_ID IS NOT NULL);
しかし、このスクリプトは完全92.67パーセント0%から取得するのに約2分かかります、それは94%に到達するために25分かけてもかかりましたコンプリート。私は最終的にスクリプトを停止しました。私はそれを数回実行しました(私は異なるインデックスとDBMS_STATSを使って遊んでいました)が、毎回92.67%になってしまいました。
私はそれが私のスクリプトでなければならないと思った。
UPDATE MONKEYS M2 SET M2.MONKEY_PUZZLE_ID =
(SELECT X.MPID FROM
(SELECT M.MONKEY_ID MID, MP.MONKEY_PUZZLE_ID MPID
FROM MONKEYS M INNER JOIN MONKEY_PUZZLES MP
ON MP.GIRAFFE_ID = M.GIRAFFE_ID) X
WHERE X.MID = M2.MONKEY_ID);
しかし、それはゴミだった:私は、戻って振り出しに戻ったバナナを食べ、「Oook」多くのことを言ったとはるかに明示され、次の変動スクリプトを、思い付きました。私のインデックスでも、2%になるのに5分以上かかりましたので、私はそれを解凍しました。
私はその後、私はとかなり満足していた以下の変動、思い付いた:しかし
UPDATE MONKEYS M SET M.MONKEY_PUZZLE_ID =
(SELECT MP.MONKEY_PUZZLE_ID
FROM MONKEY_PUZZLES MP
WHERE M.GIRAFFE_ID = MP.GIRAFFE_ID
AND EXISTS
(SELECT 1 FROM MONKEY_PUZZLES MP2
WHERE M.GIRAFFE_ID = MP2.GIRAFFE_ID));
、と私は本当に私の目を信じることができなかった、このスクリプトは、ほぼ正確に最初のように振る舞っ。約2分で実行され、0%から92.67%まで完了し、次に何かを得るために絶対的な年齢を取る。 92.67%とは何ですか?
ブロックの総数は41,717であり、大幅に減速する前に約38,000ブロックに達します。あなたが迷っている場合は
、私は%の年齢の完全なを計算するために、別のSQLPLUSセッションで次の問合せを使用しています:
(これのバリエーションです: http://searchoracle.techtarget.com/tip/Tracking-the-progress-of-long-running-queries)SELECT X.*, TO_CHAR(SYSDATE, 'HH24:MI:SS') TIMESTAMP
FROM (select sid, serial#, opname, sofar, totalwork,
round(sofar/totalwork*100,2) "% Complete" from v$session_longops) X
WHERE "% Complete" < 100 and totalwork > 0;
貧しい虎を苦しみから救うのを助けてください!
P.S.私はスクリプトを一晩中実行したままにしておき、100%に達すると午前中に更新します。
EDIT:最終的にわずか57分後に100%に達しました(それほど悪くない)が、2分で92.67%に達したと考えると、かなりひどいです!
テーブルのオプティマイザ統計を作成し、対応するステートメントの実行計画を取得します。さらに、クエリが停止しているときに待機イベントが何であるかを確認する必要があります。 – steve
実行計画は本当にここで助けになるでしょう。また、すべてのmonkeys.monkey_puzzle_idフィールドがNULLか、 'WHERE monkey_puzzle_id IS NULL'を追加すると助けになるでしょうか? – eaolson
ありがとう@eaolson。私のmonkeys.monkey_puzzle_idsはすべてnullです。 @steve、私は 'DBMS_STATS.GENERATE_SCHEMA_STATS(OWNNAME => 'JUNGLE'、OPTIONS => 'GATHER AUTO')'を使って、私が設定したインデックスの統計を生成しました。助けることができる他に何かありますか? – LordScree