10亿数据如何做到0.003ms内查询?又如何做到在0.03μs内查询?

人世间没有不能优化的查询,如果有,那就是钱花的不够。                                           
                                                                                                                 —— 佚名


已经是笔者写8eqbang的第三篇blog了,同时也是本系列的最后一篇。上次我们提到,利用二进制存储的方法可以提升四倍速度,仅需0.12ms即可完成一次查询。那是否还有更快的方案呢?答案是肯定的,并且在优化后还有更快的方案。


之前,我们的查询思路一直是二分查找,这其实就是优化问题的关键了。二分查找的时间复杂度为O(logN),虽然已经很快,但单次查询仍需大概31次数值比较。实际上,我们完全可以通过打表的手段使得时间复杂度降低到O(1),因为QQ号码本身即为整数值,只需要把表的大小开到40亿就能完全哈希。可以算出所需要的空间大小为4000000000×9b/1024/1024/1024≈33.5G,这刚好与文件实际大小完全吻合。


下图为打表法查询速度测试结果,我们可以看到在打表的情况下,单次查询时间只需要3.08微秒,远低于之前的0.12毫秒,速度提升了将近40倍,而代价仅仅是多占用了33.5-5.86=27.64(G)硬盘空间。

我们都知道往往O(1)已经是最好的算法了,那还能继续提升查询速度吗?其实不妨大胆一点,既然此方法的核心在于随机访问,那么不如就用RAM来当做8e数据最好的载体。


下图为二分法二进制文件加载到内存中查询后的结果。可以看到的是单次查询只需要1微秒了,且还是没打表的情况。同样我们可以算出,如果有64G内存的电脑,那么打表法的单次查找时间大概在27纳秒,一秒钟内计算机能对7亿数据进行3703万次查找,仅需10根内存条足以解决全国的查询需求。

附打表法和在内存里二分法的全部代码:

 

 

扫描二维码关注公众号,回复: 16248363 查看本文章

猜你喜欢

转载自blog.csdn.net/ik666/article/details/126807855