数据存储原理-查询优化

从一个简单的例子出发,通过不同数据量的阶段来看数据存储系统的演化过程,帮助大家了解数据库存储系统中查询优化的一些基本原理和思路。

例子:一个图书管理系统,有ID, BookName, Author等字段;需求是根据ID来获得书名和作者等数据。

模式一:小数据量

可以采用HashMap的形式,以ID为Key, BookName和Author作为Value;因为HashMap采用内存来保存数据,结合HashMap机制,所以这种形式的数据存储查询速度很快。

  • 单个查询:这种模式能较好的支持单个查询的操作,并且具有较好的性能。
  • 范围查询:需要对范围内的数据一个个判断并查询, 对于ID在50-150的范围查询,需要100次查询,虽然都是内存操作,但是操作次数太多。

其局限性也很明显:但是这种形式只适应于数据量不大的程序内数据缓存或查询使用。当数据量增加时,HashMap限制以及内存都会成为制约因素。

模式二:较大数据量

采用HashMap的形式,当数据量增加到超过Map或内存的限制,HashMap的方式显然就不再适用。这时候就可以考虑将数据记录放入文件中,在文件中记录每个ID对应的BookName和Author等数据, 同时在内存中维护一个索引HashMap,保存ID与文件中对应记录的Offset偏移量,因为HashMap中只保存Key和偏移量,所占用空间远小于数据的大小,所以保存更多的数据。

  • 单个查询: 根据单个ID查询数据时,首先需要根据ID从HashMap中找到对应的Offset,然后再根据Offset从数据文件中读取对应的数据。这种方式的数据查询过程分为两步,第一步在内存中操作,所用时间基本可以忽略,第二步需要fseek进行磁盘寻道一次。根据常规SATA磁盘的寻道时间10ms来计算,一次ID查询需要一次寻道时间,也就是说IOPS为100, 每秒支持最多100次查询。

  • 范围查询:同模式一类似,需要根据ID分别查询对应的Offset,并根据Offset再去一个个的查询每个ID对应的数据;例如对于ID为50-150的范围查询,需要100次寻道,耗时1秒,对于范围查询这种模式基本不可行。

局限性:对于单个查询这个模式性能还是可以认可的,但是对于范围查询,太多的磁盘寻道造成的性能是无法是忍受的。

模式三:大数据量

当数据量继续增大,模式二的索引数据也无法全部保存在内存中时,这时候就该B+树上场了,树节点分为根节点、子节点和叶节点;根节点和子节点中保存索引的范围,叶节点保存了ID对应的数据中文件中的Offset量.

  • 单个查询:这样当根据ID查询时,会从根节点开始,经过子节点的过滤,到达叶节点,从叶节点中读取ID对应的Offset值,然后再从数据文件中根据Offset得到数据。一般情况下,根节点和子节点可以保存在内存中,而叶节点和数据则保存在磁盘上。这样整个查询过程需要多次内存查询和两次磁盘寻道,内存查询时间可以忽略,两次寻道(根据ID查找Offset,根据Offset得到数据),所以其每秒最多支持50次查询。

  • 范围查询:要查询ID为50-150的所有记录的书名和作者,如果还采用上述处理方式会有什么样的结果呢?首先如果50-150包含100个记录,则需要100次的寻道找出这100个ID对应的Offset, 然后再需要100次寻道找出每个ID对应的数据,共需要200次寻道,耗时2秒,显然这是无法忍受的。

针对范围查询的优化

上述模式都面临同一个问题,无论数据结构怎么变,都无法解决范围查询的低效率问题。要解决这个问题,我们需要分析磁盘的特点以及数据查询的特点。磁盘的特点是顺序读写速度要远大于随机读写速度,而范围查询一般都是连续的;所以我们的思路是将原来的随机读写转化为顺序读写。根据这个思路,我们将磁盘上的数据进行排序和划分Page,首先进行Page分割,每个Page包含一个或多个数据记录,Page与Page之间是有序的,但是Page内部是无序的。这样在B+树的叶节点就要保存数据的Page和Page内的偏移量;并且磁盘读取数据时是按照Page来读取,每次读取一Page,Page是磁盘数据读取的最小单位.

对于50-150的范围查询,如果数据落在多个Page中,则会从磁盘上一次将数据对应的Page全部读进内存,因为是顺序读写,速度近似为一次fseek。采用这种方式,范围查询从200次寻道减少为2两次寻道(一次根据ID找Page, 一次读取Page),基本满足了查询的性能要求。

结束语

本文只介绍了数据查询的基本操作以及一些基本的优化处理思路,因为数据库数据查询性能优化是一个非常复杂的系统,实际使用的数据库与磁盘系统中采用了很多优化算法来提高系统性能,有兴趣的可以找一些专业的数据进行深入了解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值