C++-Sqlite优化

Sqlite由于是基于文件建立的数据库,所以,相对于Mysql等其他数据库相对较慢,但是在细节上,可以通过一些方法进行优化。

建立索引

处于每个表自带的ID字段,如果其他的字段,需要进行检索,最好是对其建立索引,可以极大的优化检索速度,但是建立索引会造成文件的增大,所以,在较小的数据量时,没必要建立索引:

下面是实测数据对比:

1
2
3
原始速度进行Update耗时:149ms
直接通过ID进行Update耗时:20ms
通过索引字段进行Update耗时:3ms

不生成临时日志文件

如果数据库操作并不需要进行事务支持,即不需要回滚,那么可以设置其不生成临时数据文件,以提高速度,执行命令如下:

1
2
PRAGMA synchronous = OFF
PRAGMA journal_mode = OFF

注意,这个设置是单次有效的,所以,每次在代码中openDB时,都是执行一次命令。

下面是实测数据对比:

1
2
原始速度进行Update耗时:149ms
设置不生成临时日志文件进行Update耗时:129ms

模糊检索(LIKE)

Sqlite中,使用like运算符可以进行模糊匹配,其中,可以搭配两个匹配符组合使用:

  • 百分号(%):表示零个、一个或者多个数字或字符
  • 下划线(_):表示一个数字或字符

举例:

Statement Discription
LIKE ‘abc%’ abc开头的任意字符串
LIKE ‘%abc’ abc结尾的任意字符串
LIKE ‘abc_’ abc开头的长度为4任意字符串

LIKE语句在字符串较短时,检索效率还可以,但是如果字符串较长,例如’zhengquan%’,那效率非常低,但是又需要这样的模糊时,例如:

1
name LIKE 'abc%'

可以这样优化:

1
name >= 'abc' AND name < 'abd'

并且在name字段上建立索引,可以进一步加快速度。

右边的边界就是最后一个字母加一:

1
2
char maxLast = word[word.length() - 1] + 1;
string maxPinyin = word.substr(0, word.length() - 1) + maxLast;

下面是实测数据对比:

1
2
LIKE匹配耗时:136ms
左右边界匹配耗时:42ms

清除空间

如果移除了索引,或者删除了数据,Sqlite不会立即清空其占用的空间,需要通过命令进行清除:

1
VACUUM