1

「refRecId」というフィールド/列が1つしかない、完全に空白のカスタムテーブル(DatabaseLogFixLog)があります。SysDatabaseLog(ログ)に参加しています。計画では、SysDatabaseLogをバッチで更新し、SysDatabaseLogを更新するときに、更新した行のrecIdを挿入します。私のSysDatabaseLogには370万件のレコードがあります。以下に示すnotexistsjoinとouterjoinの両方を試しました。私のコードの何が問題になっていますか?どちらもシステムを完全にロックし、デバッガーはループ内に入りません。

外部参加:

updateCounter = 10;
while select forupdate log
    order by CreatedDateTime, RecId
    outer join databaseLogFixLog
    where databaseLogFixLog.RefRecId != log.RecId
{
    counter++;

    if (counter > updateCount)
        break;

    info(strfmt("%1", counter));
}

info(strfmt("Done updating %1", counter));

Notexistsが参加します:

updateCounter = 10;
while select forupdate log
    order by CreatedDateTime, RecId
    notexists join databaseLogFixLog
    where databaseLogFixLog.RefRecId == log.RecId
{
    counter++;

    if (counter > updateCount)
        break;

    info(strfmt("%1", counter));
}

info(strfmt("Done updating %1", counter));
4

2 に答える 2

1

「forupdate」キーワードを使用してこのような巨大なデータセットをループすることはないと思いますが、ループ(log)用に1つのテーブルバッファーを使用し、更新(logUpdate)用に別のテーブルバッファーを使用します。

3.7ミルのレコードをループしている間、システムがハングすることを想像できます。クエリの実行中は、while-select内に最終的に入るまで待つ必要があります。

また、RefRecIdにテーブルのインデックスがあることを確認してください。これにより、データベースエンジンは、databaseLogFixLogで行を検索しようとして全表スキャンを実行しません。

于 2012-08-08T06:39:42.457 に答える
1

2つの結合は同等ではなく、外部結合はまったく間違っています。

参加は機能しますが、ログレコード(370万)を並べ替える必要があります。魔女には時間がかかります。また、記録が存在するかどうかを確認logFixLogする必要があります(370万ごとに)RefRecId。処理を高速化するために、フィールドにインデックスが必要になります。

速度が必要な場合は、order by句を削除してください。

キーワードを追加してみることもできます。firstfastこれにより、初期結果が速くなることがあります(ただし、と組み合わせた場合はめったにありませんorder by)。

最後に、更新するフィールドを選択します。特に、このフィールドは他のフィールドと一緒に保存されないため、コンテナフィールドは避けてください。

于 2012-08-08T09:39:02.210 に答える