首页 > 数据库 >各个数据库存二进制大文件的性能测试

各个数据库存二进制大文件的性能测试

时间:2023-12-11 10:12:33浏览次数:50  
标签:二进制 数据库 100MB 测试 100 数据 35MB blob

1前言

​ 有个项目软件前端将二进制大文件存在了indexDB,每次给后端传文件(需要传到底层C++进行调用)都会导致内存占用飙升,想着使用前后端都能共同操作的数据库来解决这个内存占用的问题,并且希望这个更具尽可能的轻量,可以嵌入到程序中是最好的,通过一个安装包进行安装。

2各个数据库的性能比较

2.1 MySQL

​ 预先准备35MB的Byte数组数据,将其存到数据库的格式为blob,测试MySQL存储100块35MB的数据需要300秒,平均一块需要3s时间。

2.2 MongoDB

​ MongoDB的数据是采用键值对的形式进行存储,一样是采用100块35MB的数据进行写入,测试需要45s时间,平均一块是450ms。

2.3 SQLite测试及优化过程

2.3.1 概述

​ SQLite使用Mybatis作为ORM框架进行100块35MB的写入速度,100块使用了12s,平均一块35MB写入速度是120ms,远快于前面两种使用Mybatis读数据库blob格式出现不支持的问题,将ORM换到JdbcTemplate后,支持blob格式,进行读,一块35MB读了40s时间,猜测是JdbcTemplate是比较落后的方案,没有针对大文件优化。

2.3.2 优化流程

(一)表结构优化

​ 主键id改为PrimaryKey,并且设置自增,使得每次都可以B+树主键索引命中查询内容。

(二)Mybatis优化

依然是换回springboot最主流的mybatis框架,手写mapper.xml文件处理blob格式,指定handler处理器编写对blob的处理,最终实现对blob的读取。优化后,对读取的数据不进行解析的话,平均一块35MB的数据读取50ms,涉及到数据解析(需要用byte数组接blob,并对整个数组中的数据解析取值)会再多一些时间。

(三)使用JPA

​ Mybatis除了对blob数据读取支持不好外,操作sqlite数据库时,使用自增id无法正常生成id的值,决定换到JPA进行尝试。

在JPA下,写100块35MB的数据如下:

image-20231013170138580

​ 可见写入速度接近于Mybatis和JdbcTemplate,都是100+ms。

​ 测试读100块35MB的数据:

image-20231013170151705

​ 读的速度得到很大提升,30ms左右,快于mybatis下的50ms。

​ 在测试35块100MB大小的数据的写操作:

image-20231013170157560

​ 写操作的时间基本成线性增长,100MB一块写入需要400ms+。

​ 再测试读操作:

image-20231013170203574

100MB的读操作性能还是很高,读一块100MB大小的分块是100+ms。(上述测试涉及到的读操作都是没有对数据进行解析的)

(四)针对写过程进行优化

​ 当前场景下,需要不断对数据库执行多个插入操作,默认情况下,每次插入一个数据都会开始事务和提交事务,多次提交会重复这个流程,磁盘I/O频率高,尝试开启事务,在数据都准备好情况下再进行提交事务。在插入的方法上加入注解@Transactional,下面测试有无@Transactional情况下存10个100MB数据的情况。

image-20231013170219657

左边是使用了注解后的结果,右边是没有,开启事务后提升是很明显的。一块100MB的分块写入从400ms降低到300ms,但会导致另外一个问题,如果35个100MB的数据同时存进去会出现java堆溢出,因为这3.5g在事务commit前都是放在内存里面导致溢出。

image-20231013170226291

(五)针对读过程尝试进行优化

​ 对读过程尝试调节了SQLite一些参数,但是基本没有提升。

设置PRAGMA synchronous = OFF,关闭写同步,PRAGMA synchronous = OFF,在 sqlite3 中 synchronous 有三种模式,分别是 FULL,NORMAL 和 OFF,在系统意外终止的时候,安全性逐级减弱,FULL模式下,保证数据不会损坏,安全性最高,写入速度也最慢。

设置PRAGMA page_size = 8192,通过设置PAGE_SIZE参数,调整最小存储单元PAGE的大小,由于存入的数据较大,尝试改成8192,甚至16384。

设置完没有提升,猜测上面参数是针对数量条数很大的情况才有提升,当前情况是数据条数不多,但单独的每条数据占用内存大。

2.4 LevelDB

​ Leveldb也是轻量级数据库,属于NOSQL,是以key-value形式进行存储,Java和node.js都能同时使用,但是经过测试,同样存入35个100MB分块大小的数据,每一块存入时间是400ms,每一块读取时间也接近400ms,相比较jpa下的sqlite表现,并没有提升。

2.5 IndexDB(原有方案)

​ 读100MB的分块是50毫秒,读性能非常的好。

image-20231013170310993

写入100MB分块的时候,算上json转blob 以及入库的时间,大概是100-200ms,时间远短于尚未做数据处理的sqlite(事务下300-400ms)。

image-20231013170326346

3 结论

上述所测试的数据库性能都不如原有方案下的indexDB,最接近indexDB的sqlite,读写性能数据比较如下:

100MB分块的写入,包括json数据解析,indexDB是100-200ms,sqlite不包括数据解析在开启事务的情况下是300-400ms,不开启事务则是400-500ms。

100MB分块的读取,不包括数据解析:indexDB是50ms,sqlite是100-200ms。

标签:二进制,数据库,100MB,测试,100,数据,35MB,blob
From: https://www.cnblogs.com/scottyzh/p/17893749.html

相关文章

  • 权威数据库市场排名出炉,腾讯爆出王炸!
    1第一!前天也就是12月6号。全球领先的IT研究和咨询公司IDC发布的《IDCMarketScape:中国分布式关系型数据库2023年厂商评估》报告(以下称“报告”)显示:腾讯云位居中国分布式关系型数据库“领导者”类别,并在市场份额上取得国内领先成绩。IDC大家都知道吧,主要在ICT和科技行业,提供行......
  • 数据库性能优化八大方案
    毫不夸张的说咱们后端工程师,无论在哪家公司,呆在哪个团队,做哪个系统,遇到的第一个让人头疼的问题绝对是数据库性能问题。如果我们有一套成熟的方法论,能让大家快速、准确的去选择出合适的优化方案,我相信能够快速准备解决咱么日常遇到的80%甚至90%的性能问题。从解决问题的角度出发,我......
  • 读程序员的README笔记07_测试(下)
    1. 自己动手编写测试1.1. QA团队可以帮助你验证你的代码是否稳定,但千万不要把代码直接丢给他们,然后让他们做所有的测试1.2. 避免硬编码的值,不要重复代码1.3. 专注于测试基本功能而不是实现细节,这有助于代码库的重构1.3.1. 测试代码在重构后仍然可以运行1.4. 将测试的......
  • 又有新框架上线了,测试、AI 通通有「GitHub 热点速览」
    本周热点之一可能就是Apple刚开源便获得8k+star的机器学习框架mlx,顺带官方开源的mlx-example(示例仓)也在热门榜上有一席之位,据说它已经跑通了大模型Llama7B,如果你最近刚入手了M3的苹果机,不妨来试试这个专为Apple芯片而生的框架。除了跑在Apple芯片上的新框架,其实......
  • mysql数据库文件丢失恢复---惜分飞
    联系:手机/微信(+8617813235971)QQ(107644445)标题:mysql数据库文件丢失恢复作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]客户服务器重启,mysql相关数据文件丢失通过底层工具进行分析,无法正确恢复数据库名字,一个个单个ibd文件(......
  • c测试
    defeval(self,phase='val',openset=False):print("Entereval")print_str=['Phase:%s'%(phase)]print_write(print_str,self.log_file)#Phase:testtime.sleep(0.25)#暂停程序执行0.25秒,以便给打......
  • 【数据库】sql server 中的sql语句--增删改查
    createdatabase学生gouse学生goCREATETABLEStudent(Snochar(7)PRIMARYKEY,Snamechar(10)NOTNULL,Ssexchar(2)check(ssexin('男','女')),Sagetinyint,Sdeptchar(20))CREATETABLECourse(Cn......
  • 17-数据库平滑扩容
    1.扩容问题B+树,一般就三层,上边两层是索引,最后一层是数据记录。扇区:4k,一页:16k假设一条数据记录:1k=>一页可以放16条记录上面两层,每一个item的结构是:[索引6B,主键8B]16k*1024=16384(B)16384/(6+8)=1170=>一层可存放1170个item1170*1170=1369234=>两层......
  • Qt6 c++教程9测试&调试
    9测试&调试调试和测试是软件开发的重要组成部分。在本章中,你将学习如何调试Qt项目、不同的调试技术以及Qt支持的调试器。调试是发现错误或不希望出现的行为的根本原因并加以解决的过程。我们还将讨论使用QtTest框架进行单元测试。QtTest是基于Qt的应用程序和库的单元测试......
  • openGauss学习笔记-151 openGauss 数据库运维-备份与恢复-物理备份与恢复之gs_basebac
    openGauss学习笔记-151openGauss数据库运维-备份与恢复-物理备份与恢复之gs_basebackup151.1背景信息openGauss部署成功后,在数据库运行的过程中,会遇到各种问题及异常状态。openGauss提供了gs_basebackup工具做基础的物理备份。gs_basebackup的实现目标是对服务器数据库文件的......