设为首页 收藏本站
查看: 1110|回复: 0

[经验分享] Sqlite数据库删除大量数据后的擦屁股工作

[复制链接]

尚未签到

发表于 2016-11-30 12:00:54 | 显示全部楼层 |阅读模式
SqlCe实在是太慢了,在执行速率和Sqlite没法比。
所以在项目的下一个版本中,准备用Sqlite替换掉SqlCe
事前做尝试工作,毕竟没有用过Sqlite
结果试了试确实不错,有两点很满意。
 
第一,执行速率就不用说了,众所周一的比SqlCe
 
第二,或许对别人来说是个鸡肋,但是我这个还挺需要的(是我想出来的笨解决方案,有什么好方案,可以帮我提提意见)
什么优点呢?压缩率。
不知道有没有人知道用winZipsqlite.db文件打过包?压缩率其实是很高的。
举个例子,同样的两个数据库,一个sqlCe.sdf文件,一个Sqlite.db文件。
其中的数据内容完全相同,在硬盘上的占用空间分别是
sqlCe3,207,168byteSqlite3,117,056byte
 
winrar进行压缩,结果分别是
SqlCe3,158,016byteSqlite1,159,168byte
 
可以看到,SqlCe压缩后,数据量基本上没有改变。而Sqlite压缩后,数据量变成了原来的将近三分之一。
这意味着什么,这意味着在网络上的传输数据量,传输时间大大节省了。
按照中国移不动的费率,大家可以省很多话费去交人头税的。
按照中国联不通的网络,可以大大节省传输时间,减少联不通的概率。
 
呵呵,其实主要是我所在的项目,每次做数据库同步的时候,如果要在手机端循环插入更新一万条数据,耗时太长,是不能容忍的。于是我愚昧的决定把数据库文件传回服务器,在服务器端更新后然后再传回给手机。于是这个压缩的问题对我来说很重要。
其次压缩对我来说还有一点很重要,我是通过soap的方式传递数据的。就通过XML,这个方法很笨但是实现起来简单。问题就在于将3M以上的文件序列化到xml里面,传递是会无端的出问题。
我就在一台还没有发售的机器上遇到过StringBuilder的错误,Soap底层对XML处理是用到了StringBuilder,这个时候就出过问题。我考虑就是因为3M的数据太大了。(只是猜测,我下午专门对这个机器进行测试)
所以以上种种原因,我需要一个在网络上传输最“轻量”的方式。无疑就是压缩了。
 
说了这么多,没进主题,我的主题是给Sqlite在删除数据后擦屁股。
大家或许发现了,当你在sqlite中删除了大量数据后,数据库文件的大小还是那样,没有变。
就用我的项目来说,3M的数据删除后,sqlite.db文件依然是3M,而我要的结果实际上只有35K,在压缩一下也就10K了。为什么会出现这个问题,SqlCe.sdf文件是即删即减的。
 
原因是:
当你从Sqlite删除数据后,未使用的磁盘空间被添加到一个内在的空闲列表中用于存储你下次插入的数据。磁盘空间并没有丢失。但是也不向操作系统返回磁盘空间。(嘿嘿,Sqlite.orgFAQ中提到过这个问题)
 
解决方法:两种
一,在数据删除后,手动执行VACUUM命令,执行方式很简单
 
objSQLHelper.ExecuteNonQuery(CommandType.Text,"VACUUM")
 
VACUUM命令会清空“空闲列表”,把数据库尺寸压缩到最小。但是要耗费一些时间。
FQA里面说,在Linux的环境下,大约0.5/M。并且要使用两倍于数据库文件的空间。
我憎恨此FQA,他只说系统环境,不说机器硬件环境。我在测试手机上执行用了将近13秒时间压缩了将近3M的空间。至于它所占用的另一部分空间,是生成了一个.db-journal后缀名的临时文件。(这个问题对我现在来说是无所谓的。)
 
二,在数据库文件建成中,将auto_vacuum设置成“1”。
注意:只有在数据中未建任何表才能改auto-vacuum标记试图在已有表的情况下修改不会导致报错
cmd.CommandText = "PRAGMA auto_vacuum =1;"
cmd.ExecuteNonQuery()
当开启auto-vacuum,当提交一个从数据删除除数据的事物时,数据文件自动收缩。
数据会在内部存一些信息以便支持一功能,使得数据文件比不开启该选项时稍微大一些。
我的表结构,不含任何数据是,数据库文件大小是25K左右,开了auto_vacuum之后是26K
插入运行基础数据后,文件变成35K,开了auto_vacuum之后是36K
变化不大,无所谓。
 
但是第二个方法同样有缺点,只会从数据库文件中截断空闲列表中的页, 而不会回收数据库中的碎片,也不会像VACUUM 命令那样重新整理数据库内容。实际上,由于需要在数据库文件中移动页, auto-vacuum 会产生更多的碎片。而且,在执行删除操作的时候,也有那个.db-journal文件产生。
要使用auto-vacuum,需要一些前题条件。 数据库中需要存储一些额外的信息以记录它所跟踪的每个数据库页都找回其指针位置。 所以,auto-vacumm 必须在建表之前就开启。在一个表创建之后, 就不能再开启或关闭 auto-vacumm
 
其实按照运行时间上的比较,两个在做了大删除操作后,从3M变到35K的时间其实差不多,执行VACUUM命令稍微长一点,但是也长不了多少,相对而言,这种一点点的长可以忽略不计。
加上AUTO的方式对碎片的造成情况,如果数据交换次数多的话,这种方式很不合适。
还是决定用第一种方式,在大数据删除后,向服务器送信前。执行VACUUM命令。这样做比较划算。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-307733-1-1.html 上篇帖子: android SQLite数据库基本操作示例 下篇帖子: SQLite用于其他开发平台(Java和.NET)的包装库
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表