2009-03-01 1 views
3

ハードドライブの検索方法を理解しようとする人がいます。データベース構造とハードドライブのシーク時間の混乱

私は読取りパフォーマンスが絶対に必要不可欠な小さなバイナリデータベースファイルを持っています。ファイル内で数バイトをスキップする必要がある場合は、seek()またはread()を使用して不要なデータを破棄する方が速いです。

平均は、ハードドライブのシークタイム10msの場合で、読み出し速度は、それが(読むために迅速だと算出した300メガバイト/ sのIである)(求めるより)3メガバイトよりも小さい値を持ちます。本当ですか?既存のストリームを読んでいない新しいシークを実行するときにオーバーヘッドはありますか?

あなたは、インデックスのより適切なファイル構造と思いますか?

Entry1:Value:PointerIntoToData 
Entry2:Value:PointerIntoToData 
Entry3:Value:PointerIntoToData 
Data, Data, Data 

Or 

Entry1:Value:Data 
Entry2:Value:Data 
Entry3:Value:Data 

値が正しくない場合にエントリを読み取ると、無視されます。だから、それが迅速にファイルをされたストリーミング時:エントリが使用することを必要とされていない場合に求める 1.()のエントリーが必要とされないとき2. その上をスキップすることが、データ 3.または使用最初の構造を捨てる読みますエントリが必要な場合は、最後のデータリポジトリへのseek()が必要です。

エントリは4バイトで、値である8バイト&データがどのように "絶対に必要" 12キロバイト

乾杯

答えて

4

すべて求めるシステムコールは、次の読み取りがされるファイル内の位置を変えているん心配します。ドライブヘッドは移動しません。データが読み書きされるとドライブヘッドが動き、次に実行するOSを直接制御することはできません。

あなたが必要としない多くのデータを読み取ることは、すべての読み取りデータがOSバッファにスペースを必要とし、古いデータを破棄するため、影響があります。したがって、大きなファイルをシークすると、ファイルシステムのキャッシュが少なくなります。


私が書いたのは、データベース全体をメモリに収めることができないと仮定したものです。できるなら、それをやりなさい。すべてを読んで、ファイルの最後に新しいデータや変更されたデータを追加しようとします。無駄なスペースについて心配する必要はありません。しばらくしてからコンパクト化をしてください。


データベースが大きすぎる場合:

データが読み込まれ、ブロック(またはページ)で、物理ドライブに書き込まれます。同様に、OSのディスクIOの基本単位はpageです。 OSがディスクからデータをキャッシュすると、ページ全体にも表示されます。したがって、シークまたはリードを使用して数バイトを前進させる必要があるかどうかを考えてもほとんど意味がありません。高速化したい場合は、ディスクIOが実際にどのように機能するかを考慮する必要があります。

最初に、既にnobugzによって言及されています。各操作で使用するデータがファイル内に接近して配置されている場合、OSは少ないページを読み書きする必要があります。一方、データを広げると、多くのページを一度に読み書きする必要がありますが、これは常に遅くなります。

インデックスのデータ構造について。通常は、B-treesとして整理されています。これは、ページングされた読み書きを使用してメモリに格納された大量のデータを効果的に検索するために特に作られたデータ構造です。

データを整理するための両方の戦略が実際に使用されます。たとえば、MS SQL Serverはデフォルトでデータを最初に格納します。データは別々に格納され、索引には索引付き列のデータとファイル内のデータ行の物理アドレスのみが格納されます。しかし、クラスタ化インデックスを定義すると、すべてのデータがこのインデックスに格納されます。他のすべてのインデックスは、物理アドレスの代わりにクラスタ化インデックスキーを介してデータを指します。最初の方法は単純ですが、クラスタ化インデックスに基づいてデータの範囲をスキャンすることが多い場合は、もう1つの方がはるかに効果的です。

3

ですアクセスを求めているのですか?最適ではないソリューションでアプリケーションをテストしましたか?このテストでは、の実際ののボトルネックがどこであるかを判断するためにベンチマークを実施しましたか?あなたがしていない場合、あなたは結果に驚かれるでしょう。

次に、異なる方法を試して、実行時間を比較してください。さまざまなシステム負荷でテストします(アプリケーションを除いてシステムがアイドル状態のとき、ビジー状態のときなど)。

は新しい、より高速なハードドライブは、窓の外にあなたの仕事を投げる異なる内部の最適化を持っている場合、あなたの現在のハードドライブに基づいて最適化が不正になることがあり考えてみましょう。

+0

私はまだプログラムをテストしていませんが、まだ別のファイル構造を探しています。ミリ秒ごとに、私は理論上の最大値に興味があります。だから、私はあなたが気づくために働くテスト環境が必要だと思いますか?ハードドライブが別のプロセスからロードされている可能性があります。ありがとう – user72523

+0

あなたが主張しているように、毎ミリ秒ごとに、データベースをメモリに読み込んでみてください。あなたはそれがあなたのシステムメモリに簡単に収まるように、それは小さいと言います(あなたは3Mを引用します)。 しかし、速度が実際の要件か想像上の要件かどうかを判断する必要があります。あなたはなぜスピードが必要ですか? –

+0

非常にまれで病理学的な構成のみでは、ハードウェアの特性が非常に短期間を除いてソフトウェアのパフォーマンスを最適化するのに役立つと思っています。そして、徹底的なテストの後まで。ハードウェアの変更が速すぎると、「試してみるもの」のリストが上に移動します。 – dkretz

1

シーケンシャルリードは常にヘッドシーク(ポジションシークではない)を必要とするものよりも速い。シーケンシャル読み取りの一般的なハードドライブのパフォーマンスは50〜60 MB /秒で、最悪の場合〜0.4 MB /秒まで低下します。ドライブヘッドが配置されると、基本的にシリンダー内のデータを無料で入手できます。ファイルシステムのキャッシュは、シリンダからセクタを先読みすることによってそれを利用します。

しかし、ディスクシリンダ上のデータの配置を制御することはできません。また、ドライブジオメトリを推測することもできません。ボリュームが断片化すると、スループットが大幅に低下する可能性があることに注意してください。メモリ内のデータをキャッシュすることによってperfを探す必要があります。その時点で、あなたはおよそlocality of reference.

+0

ヘッドとポジションシークの違いは何ですか?ファイル内では、シリンダが常に隣接している(ext3)と推測できませんか?データは個別に読み取られる32MBのチャンクに分割されますが、チャンクの量はメモリに一度にキャッシュできないことを意味します。 – user72523

+0

@unknown、あなたはハードディスクのシークメカニズムとシステムコールを混同しています。実際には、読み込みを呼び出すことによるメモリオーバーヘッドが発生しないので、おそらく呼び出す方がよいでしょう。しかし、これはアプリケーションの仕様によって異なります。 – BobbyShaftoe

+0

@Bobby - あなたの権利私は混乱しています。 seek()システムコールは常に頭を動かすわけではありませんか?別のシリンダーへの移動が必要な場合のみ? – user72523

0

いつでもファイルをメモリにマップし、ポインタなどでアクセスできます。これにより、通常はアクセスがより簡単になります