1

私は大規模な sqlite3 (3.6.22) データベース (約 1 GB、500 万行) を持っており、1 つの列にインデックスが付けられた単一のテーブルがあります。問題は、通常の INSERT トランザクションを実行する時間が大きく変動することです。一度に約 10000 行を挿入します (もちろん、トランザクションにラップされます)。多くの場合、約 1.5 秒かかりますが、約 5 トランザクションごとに、まったく同じトランザクションが完了するまでに突然数分かかります。私は多くの実験を行いましたが、インデックスがある場合にのみ現象が発生することを発見しました。これにより、インデックスの更新に多くの時間がかかると思われます。

もっと一貫したパフォーマンスが必要です。一部のトランザクションが前のトランザクションの 200 倍の時間が突然かかることを避けることができれば、平均挿入時間は少し高くても問題ありません...どうすればよいですか?

これがスキーマです。blocks.md5 の文字列は常に正確に 32 バイトの長さで、おそらく一意です。Rolling.value 列には、非常に大きな 64 ビット整数が含まれます。

CREATE TABLE blocks (blob char(32) NOT NULL, 
                     offset long NOT NULL, 
                     md5 char(32) NOT NULL, 
                     row_md5 char(32));
CREATE TABLE rolling (value INT NOT NULL);

CREATE INDEX index_md5 ON blocks (md5);
CREATE UNIQUE INDEX index_rolling ON rolling (value);
4

1 に答える 1

1

sqlite インデックスがどのように実装されているかは正確にはわかりませんが、インデックスをディスクに保存したり、データを並べ替えたりする場合は、あなたが説明した動作が期待できます。

インデックスにブロックを割り当てるときに、データ用の N スロットでページを開始するシナリオを想像してみてください。ページがいっぱいになると、別のページを割り当ててデータを分割する必要があります。

データを挿入するとき、MD5 の順序は可能な限りランダムになるため、すべてのページが個別にいっぱいになります。インデックス作成戦略がそれを知る合理的な方法はありません。

他のデータベースは、特にランダムな MD5 のような場合に、文字列に対して通常とは異なるインデックス戦略を使用することを推奨しています。

すべてのメモリ データベースでこれを実行しようとすると、アルゴリズム アクセスかディスク アクセスかがわかります。

挿入する前にデータをソートできるオフラインシステムでこれを回避しようとしただけです。すべて挿入した後、インデックスを作成しましたが、これは可能な限り高速でした。一度に 10k を実行している場合は、それがユース ケースになる可能性がありますが、私にはわかりません。

于 2013-03-28T05:34:42.737 に答える