知识卡片
索引是读写速度的权衡额外结构总会拖慢写入
内容
最简单的数据库可以用两个函数实现:写入时把键值对追加到一个仅追加的文件末尾,读取时 从头到尾扫描文件找到某个键最后一次出现的位置。追加写入本身性能很好,因为顺序写入 磁盘通常非常高效;但这种设计的读取代价是O(n)——记录数翻倍,查找时间也翻倍,数据量 大了就完全不可用。为了让查找变快,需要额外的数据结构:索引——保存一些额外的元数据 作为路标,帮助更快找到目标数据。但索引不是免费的:它是从主数据衍生出来的附加结构, 只影响查询性能、不改变数据内容本身,然而维护这份额外结构本身有开销,尤其体现在写入 上——写入性能很难超过简单的追加写入,因为追加写入是最简单的写操作,而任何类型的 索引都会在每次写入数据时需要同步更新索引,从而拖慢写入速度。这正是存储系统里一个 根本性的权衡:精心选择的索引能显著加快读查询,但每一个额外的索引都会拖慢写入;正因 如此,数据库默认不会给所有内容自动建索引,而是需要程序员或DBA基于对应用查询模式 的了解手动选择索引——选出能给应用带来最大收益、同时不引入不必要开销的那些索引。
参考来源
- 位置:《数据密集型应用系统设计》第三章《存储与检索》"驱动数据库的数据结构"
(源文件:_epub-src/ch3_split_000.html)
- 结论依据:原文用两个Bash函数示例说明仅追加写入配合线性扫描查找的O(n)查找代价,
引出索引概念,并明确指出"精心选择的索引加快了读查询的速度,但是每个索引都会
拖慢写入速度",因此数据库默认不索引所有内容,直接支撑本卡片结论。
- 原始内容:为了高效查找数据库中特定键的值,我们需要一个数据结构:索引……写入
性能很难超过简单地追加写入文件,因为追加写入是最简单的写入操作。任何类型的索引
通常都会减慢写入速度,因为每次写入数据时都需要更新索引……精心选择的索引加快了
读查询的速度,但是每个索引都会拖慢写入速度。