3

データベースを開いたり閉じたりするメソッドの実行時間を測定し、クエリと挿入を実行しています。これら 4 つの操作のそれぞれについて、基本的に、関連するステートメントの実行前後の時間を次のように取得します。

for(int i = 0; i < 500; i++) {
    startTime = System.nanoTime();
    long insertResult = db.insert(tableName, null, contentValues);
    endTime = System.nanoTime();
    if(insertResult > -1) {
        generateNoteOnSD(fileName, (endTime - startTime));
    }
}

インサートの場合:

  • サンプルの最小実行時間は 13 ms (ミリ秒) です
  • サンプルの最大実行時間は 537 ミリ秒です
  • 結果セットの 50% 強 (500 回からの 259 回の「挿入」実行) は、15 ~ 20 ミリ秒です。
  • 20 ミリ秒を超える値は、周波数が非常に低くなります (1、2、または 3)。

この種の操作がシステムによってどのように実行されるかについて、アイデア/方向性を教えてください。ストレージを永続化するための書き込み操作がどのように行われるのか、またそれがどのような要因に依存するのかはよくわかりません。上記の測定値を説明しようとするためにこれを知りたいです(同じ操作の実行時間の変動の理由)。

どんな助けでも大歓迎です。

オクタビオ

4

1 に答える 1

2

これは一時テーブルではなく、通常のテーブルであると想定します。

ここで最大のパフォーマンス ホッグから始めましょう。

デフォルトでは、そのような挿入ごとに新しいトランザクションが開始および終了します。これを大幅にスピードアップしたい場合は、適用してください

db.beginTransaction();

あなたのループの前に、そして

db.setTransactionSuccessful();
db.endTransaction;

ループの後。これにより、すべての挿入が同じトランザクションに配置されます。db.endTransaction費やされた合計時間の一部が移動した時間を必ず測定してください。これらの操作を手動で呼び出さなかった場合、db.insertいずれにせよ、それぞれが暗黙的にそれらにラップされ、これは暗黙的なトランザクションと呼ばれます。

トランザクション プロトコル自体は複雑であり、パフォーマンスの違いの一部を説明していますが、きめの細かいトランザクションにはハードウェア速度の違いが伴います。トランザクションは永続的である必要があるため、フラッシュ メモリへの書き込みが必要になります (書き込みは読み取りよりもさらに遅く、トランザクションごとに複数の書き込みが必要です)。対照的に、「1 つの長いトランザクション」は揮発性メモリに書き込みます。コミット中にデータをフラッシュに移動する必要がある場合でも、書き込みの一部しか必要ありません。より多くの行がフラッシュ メモリ ブロックに収まり、一度に書き込まれるため、行が狭い場合、この効果はより明確になります。

読み取りに関する限り、トランザクションはここではあまり役割を果たしません。簡単です。アプリケーションが揮発性 RAM でホットな場合、すべてのデータはそこから移動します。そうでない場合、データはフラッシュから取得されます。

データの急増は、データベースと競合する無関係なバックグラウンド プロセスに起因する可能性があります。これは、これらのアプリケーションが集中的な計算を行う場合にのみ発生します。これらのプロセスの一部が同じデータベースにアクセスすると、ロックの競合が発生する可能性もあります。これは、それらのプロセスが他の何かを待っている場合でも可能です。これは、それらの分布が非常に不規則である理由も説明します. これが唯一の可能性ではありません。

SQLite で使用されるアルゴリズムの一般的な概要については、競合するオペレーティング システム用に書かれていますが、この本を参照することをお勧めします。

于 2012-07-16T22:34:33.790 に答える