0

私は次のようなアプリケーションを持っています:

delete from tableA where columnA='somevalue' and rownum<1000

次のようなサイクルで:

 while(deletedRows>0) {
    begin tran
    deletedRows = session ... "delete from tableA where columnA='somevalue' 
    and rownum<1000"....
    commit tran

}

数回実行され(各削除には20秒近くかかります)、長時間ハングした後はなぜですか?修正することは可能ですか?ありがとう。


削除が単一のSQLステートメントとしてではなくループで実行される理由は、ロールバックスペースが不足しているためです。詳細については、この質問を参照してください。

4

2 に答える 2

1

クエリが最初からテーブルをスキャンするたび。したがって、delete()する行がないゾーンをスキャンしますcolumnA='somevalue'。それらはテーブルの最初のブロックからますます遠くにあります。

columnA='somevalue'テーブルが大きく、クエリがない場合は、条件のすべての行を確認するのに時間がかかります。

あなたができることは、にインデックスを作成することですcolumnA。この場合、エンジンはその条件の行がどこにあるかをより速く認識します(インデックスの検索は指数関数的に速くなります)。

別の可能性として、コンカレントシステムを使用している場合、削除しようとしている行を誰かが更新したが、トランザクションをコミットしていないため、行がロックされている可能性があります。

于 2013-01-09T09:30:46.480 に答える
1

あなたはおそらく多くの異なる問題に遭遇します。データベースがハングしていると言っているように、主な理由は、データベースでORA-00257アーカイバエラーが発生していることです。

削除するたびにREDOベクトルが生成され、すべてのREDOがアーカイブログにダウンロードされます。アーカイブログスペースが使い果たされると、セッションがハングし、誰かがスペースを解放するまでスタックしたままになります。通常、DBAには、アーカイブログバックアップを1時間ごとに実行するジョブがあり(データベースのワークロードなどに応じて、数時間ごと、または5分ごとになる場合があります...)、バックアップが完了した後、すべてのセッションが正しく続行されます。

データベースの構成によっては、クライアントの観点からはエラーが表示されない場合がありますが、スペースが解放されるまでセッションが待機する動作が説明されているだけです。

設計に関しては、ループ内のDELETEは適切ではないという点で他のユーザーに同意します。単一のDELETEステートメントの代わりにこのループを実行しようとしている理由を知ることは興味深いかもしれません。

于 2013-01-09T10:43:55.590 に答える