可能有人帮助我试图了解硬盘寻求工作的方式.
我有一个小的二进制数据库文件,读取性能是绝对必要的.如果我需要跳过文件中的几个字节,可以更快地使用seek()或read()然后丢弃不需要的数据.
如果硬盘的平均寻道时间是10ms,读取速度是300MB / s,我计算出读取()的速度比使用小于3MB的seek()快.是真的?执行新搜索时是否存在开销,读取现有流没有?
您认为哪个是索引的更合适的文件结构.
Entry1:Value:PointerIntoToData
Entry2:Value:PointerIntoToData
Entry3:Value:PointerIntoToData
Data, Data, Data
Or
Entry1:Value:Data
Entry2:Value:Data
Entry3:Value:Data
如果值不正确,则在读取条目时将忽略该条目.因此,当流式传输文件时,它更快:
1.当不需要输入时,使用seek()跳过它
2.当不需要输入时读取它然后丢弃数据
3.或者使用第一个结构,当一个条目需要seek()到最后的数据存储库时.
条目是4个字节,值是8个字节&数据是12KB
干杯
解决方法:
所有搜索系统调用都会改变文件中下一次读取的位置.它不会移动驱动头.读取或写入数据时驱动器头会移动,而您无法直接控制下一步操作系统.
读取大量您不需要的数据会产生影响,因为所有读取数据都需要OS缓冲区中的空间并导致丢弃旧数据.因此,使用seek over big files会减少文件系统缓存.
我在下面写的所有内容都假设您不能将整个数据库放在内存中.如果可以的话,就这样做吧.读取所有内容并尝试在文件末尾附加新的和更改的数据.不要担心浪费空间,偶尔做一些压缩.
如果您的数据库太大:
数据以块(或页)形式读取和写入物理驱动器.同样,操作系统中磁盘IO的基本单元是页面.如果操作系统从磁盘缓存数据,它也在整个页面中.因此,考虑是否需要使用搜索或读取向前移动几个字节毫无意义.如果你想快速完成,你需要考虑磁盘IO的真正工作方式.
首先,nobugz已经提到过,参考地点.如果您在每个操作中使用的数据位于文件中,则操作系统将需要读取或写入较少的页面.另一方面,如果您传播数据,则需要一次读取或写入许多页面,这将始终很慢.
至于索引的数据结构.通常它们被组织为B-trees.它是一种数据结构,专门用于通过分页读写来有效搜索存储在内存中的大量数据.
并且在实践中使用这两种组织数据的策略.例如,MS SQL Server默认以第一种方式存储数据:数据单独存储,索引仅包含索引列中的数据和文件中数据行的物理地址.但是,如果定义聚簇索引,则所有数据都将存储在此索引中.所有其他索引将通过聚簇索引键而不是物理地址指向数据.第一种方法更简单,但如果您经常根据聚簇索引扫描数据范围,则另一种方法可能更有效.