SQLite的Insert性能优化
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQLite的Insert性能优化相关的知识,希望对你有一定的参考价值。
参考技术A 情景描述:SQLite作为中间层,存放客户端post来的原始数据,一行为一条记录,服务器接收到数据后解析并保存到SQLite里。遭遇战:当post来的数据有10w行时,客户端response响应慢,10w条记录服务器解析5-7s完成,但是SQLite的插入需要14-20s完成,客户端的response响应需要37-45s完成(SQLite事务已开启)。因此开启了我的Insert性能调优之旅。
解决之旅:
去博客淘金,去SQLite官网筛沙子,找来了一些解决办法
1.先说一下最开始的想法:最普通的循环insert插入语句--->拼接insert插入语句(看个人业务需求,我的就不合适)--->提交事务的insert语句(最开始的思路,但还是不能满足我的需求)。
2.关闭写磁盘同步问题 PRAGMA synchronous = OFF; 然而这个好像只能在C的API(sqlite3 自己去网上查如何使用)里使用。
指令含义 :查询"synchronous"标记的设定,返回整数值;
如何设置:
PRAGMA synchronous = FULL; (2)
PRAGMA synchronous = NORMAL; (1)
PRAGMA synchronous = OFF; (0)
3. 修改缓存大小 PRAGMA cache_size; 同样是在C的API里可以使用
4. 预处理SQLite语句(黑暗中的曙光),这个概念我最开始也是在sqlite3里看到的,但是我的逻辑都是.net实现的,这个预处理在哪里,然后去读了MSDN的SqlCommand类(SqlCommand.Prepare Method),实现了SQLite的插入需要9-11s完成,客户端的response响应需要17s左右完成( https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.prepare?view=netframework-4.8 )。
注释:SQLite的insert的操作,插入的字段字符数量的大小也有影响
sqlite性能优化
1、数据库性能上
1.1 批量事务插入,提升数据插入的性能
由于sqlite默认每次插入都是事务,需要对文件进行读写,那么减少事务次数就能简书磁盘读写次数从而获得性能提升。
1.2 单条sql优于多条sql
实测发现,对于几十条sql插入当你替换成单条sql时性能有所提升,但是这里要注意的是,换成单条可读性较差,同时会出现sql超长的错误。
1.3 读和写操作是互斥的,写操作过程中可以休眠让读操作进行
由于第一步所说的多数据事务插入,从而会导致插入时间增长那么也会影响数据展示的速度,所以可以在插入过程中休眠操作,以便给读操作流出时间展示数据。
1.4 使用索引
适当的索引的好处是让读取变快,当然带来的影响就是数据插入修改的时间增加,因为还得维护索引的变化。不过对于大部分的读操作多于写操作的数据库来说索引还是十分有必要的。关于如何设计索引,可以参考下面这个文章:
1.5 使用联合索引
过多的索引同时也会减慢读取的速度,很典型的一个情况就是比如要同时根据省市区县查询,又可以根据年月日查询,如果每个都做索引那么读取速度将会显著降低。
对于这种有层级关系的关键字,就可以考虑联合索引了,比如首先根据省查询,然后根据省市查询,层层递进到省市区县的查询方式,就可以使用联合索引,效果非常好。
1.6 勿使用过多索引
1.7 增加查询条件
当你只要一条数据时增加limit 1,这样搜索到了后面的就不会再查询了,大大的加快了速度
1.8 提前将字段的index映射好
减少getColumnIndex的时间,可以缩短一半的时间
2、数据库设计上
2.1 通过冗余换取查询速度
2.2 减少数据来提升查询速度
比如下拉操作时,先清除旧数据,再插入新数据保证数据库中的数据总量小,提升查询速度。
2.3 避免大数据多表的联合查询
和2.1的方式其实是一样的原理,只是这里需要特别拿出来说明以下,比如有文件表,还有多媒体文件表,你可以设计成一张文件表,一张多媒体关联表存放多媒体数据,文件信息还是在文件表中,然后通过外键关联。
但是如果两个表数据很多,主键还不一致同时数据从服务器下来的数序也不一致那么,两个表的联合查询出来的数据要慢的多,这个时候就可以用冗余来唤起查询速度了。
以上是关于SQLite的Insert性能优化的主要内容,如果未能解决你的问题,请参考以下文章