可遇不可求的Question之SQLLite操作百万级数据的优化篇

描述:

SQLite数据库本质上来讲就是一个磁盘上的文件,所以一切的数据库操作其实都会转化为对文件的操作,而频繁的文件操作将会是一个很耗时的过程,会极大地影响数据库存取的速度。例如:向数据库中插入100万条数据,在默认的情况下执行相应的操作,就会打开和关闭文件100万次,所以速度当然会很慢。

分析:

在入库和更新过程中按照数据库事务的思想进行设计:SQLite执行入库、更新操作的方式是,语句执行对象句柄调用库函数打开文件、调用函数执行sql语句、关闭文件。这样的执行方式对于数量级别超大的文件的弊端就是每次执行sql语句的时候都要打开文件(假设百万级数量级的数据,就要打开和关闭文件百万次),对于数据库的入库和更新操作时间主要都浪费到了文件的打开和关闭操作上,所以这里增加事务以解决该问题.

解决:

SQLite数据库是支持事务操作的,于是我们就可以通过事务来提高数据库的读写速度。事务的基本原理是:数据库管理系统首先会把要执行的sql语句存储到内存当中,只有当commit()的时候才一次性全部执行所有内存中的数据库。同时,在.NET中对数据的操作还可以采用预编优化的方式来提升性能,这种方式是采用IDbCommand的Prepare方法来进行的。

示例:

以下引用网络上的一个示例数据来说明一下效果

引用地址:http://www.cnblogs.com/Kevin-moon/archive/2008/12/01/1344658.html

A、系统环境
OS:Windows XP Professional Server Pack 
3
CPU:AMD K8 
3200+(2.2G)
RAM:3G
HD:Seagate 160G IDE 7200RPM

B、代码环境
NET2.
0、Access2003、Firebird 2.1.1.17910、SQLite 3.6.3
Firebird Data Provider(FirebirdSql.Data.FirebirdClient.dll, 
2.1.0.0)
SQLite Data Provider(System.Data.SQLite, 
1.0.60.0)

下是测试数据,仅予参考
测3次平均,无测10W
+,因Firebird出现OutMemoryException
无测修改操作,因无需求
依序 
110100100010000 条数据,单位 ms

新增操作
1.无预编, 无事务
Access:
4154195161016187
Firebird:
919189192922125
SQLite:
327867500253603

2.事务控制
Access:
3950162127812366
Firebird:
1130605875904
SQLite:
441073739

3.预编译优化
Access:
43501289089100
Firebird:
213128132215954
SQLite:
426465462654608

4.预编译+事务控制
Access:
42461026766355
Firebird:
34222112087
SQLite:
34841378

查询比较
Access:
39424051181
Firebird:
23151311294
SQLite:
11316165


讨论:
Firebird性能不如预期、SQLite性能很好
Access事务支爰不强,但预编启性能很好
SQLite缺省已预编,加上事务控制性能更好
Access查询加排序,数据10W
+时性能极差(I/O问题)
单测Firebird 10W
+新增操作,性能极差(I/O问题)
10W
+数据操作性能多卡在I/O,不过SQLite因规格单纯,所以性能会较强

总结:

1.通过事务一次提交多条SQL语句,以减少SQLLite数据的IO操作,可以有效提升大数据量操作的性能.

2.通过.NET中的预编译优化方式,即采用IDbCommand的Prepare方法来配合事务执行大批量SQL操作,可以进一步优化其性能.

原文地址:https://www.cnblogs.com/tigerjacky/p/1961498.html