性能优化与调优知识图谱《简书与写作》

SQlite 优化和不常用语法

2020-11-10  本文已影响0人  zcwfeng

SQLite PRAGMA

SQLite 的 PRAGMA 命令是一个特殊的命令,可以用在 SQLite 环境内控制各种环境变量和状态标志。一个 PRAGMA 值可以被读取,也可以根据需求进行设置。

要查询当前的 PRAGMA 值,只需要提供该 pragma 的名字:

PRAGMA pragma_name;

要为 PRAGMA 设置一个新的值,语法如下:

PRAGMA pragma_name = value;

设置模式,可以是名称或等值的整数,但返回的值将始终是一个整数

journal_mode Pragma

journal_mode Pragma 获取或设置控制日志文件如何存储和处理的日志模式。语法如下::

PRAGMA journal_mode;
PRAGMA journal_mode = mode;
PRAGMA database.journal_mode;
PRAGMA database.journal_mode = mode;

这里支持五种日志模式:

Pragma 值 描述
DELETE 默认模式。在该模式下,在事务结束时,日志文件将被删除。
TRUNCATE 日志文件被阶段为零字节长度。
PERSIST 日志文件被留在原地,但头部被重写,表明日志不再有效。
MEMORY 日志记录保留在内存中,而不是磁盘上。
OFF 不保留任何日志记录。
WAL write ahead log,3.7.0引入,日志中记录修改页,提交时只需刷修改页

在3.7.0以后,WAL(Write-Ahead Log)模式可以使用,是另一种实现事务原子性的方法。

SQLite优化

索引

简单地说,索引是一个指向表中数据的指针。一个数据库中的索引与一本书的索引目录是非常相似的。
拿汉语字典的目录页(索引)打比方,我们可以按拼音、笔画、偏旁部首等排序的目录(索引)快速查找到需要的字。

索引分类

create index id_index on user(id);
create unique index id_cindex on user(id);
create index cx_index on user(id,name);

使用场景

索引使用规则

create index complex_index on user(id,name);
select * from user where id >3;--使用了索引
select * from user where name like 'z*'; --未使用索引
--检验是否使用了索引
sqlite> explain query plan select * from user where id >3;
QUERY PLAN
`--SEARCH TABLE user USING INDEX sqlite_autoindex_user_1 (id>?)
Run Time: real 0.000 user 0.000000 sys 0.000000
sqlite> explain query plan select * from user where name like 'z*';
QUERY PLAN
`--SCAN TABLE user
Run Time: real 0.001 user 0.000000 sys 0.000000
 select * from user where cast(id as char) ='3';
 --检验
explain query plan select * from user where cast(id as char) ='3';
QUERY PLAN
`--SCAN TABLE user
Run Time: real 0.001 user 0.000000 sys 0.000000

使用事务

使用事务的两大好处是原子提交和更优性能

其他优化

神级优化(了解)

DELETE模式不支持读写并发,WAL模式模式支持读写并发,不支持读写并发影响很多情况下会导致查询和写入一方会非常慢严重影响用户体验,然后即使开启了WAL模式,程序上也要相应处理不然一样不能读写并发,要做到sqlite3读写并发两大条件:1,开启WAL模式;2,要采用多连接(至少两连接,一读一写)

开启方法

 pragma journal_mode=WAL;
 --多线程并发
 pragma sqlite_threadsafe = 2;

android代码开启

SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", 
cursorFactory,CREATE_IF_NECESSARY, myDatabaseErrorHandler);
db.enableWriteAheadLogging();//开启WAL模式

合适的索引能大幅提高性能,联表查询,大数据量表杜绝联表查询改成几个查询,由程序实现相关功能性能会高的多

分表分库已经是优化单个sql的效率数据库层面最终极的方案

分库减少文件体积;mmap接口;不清空wal文件等

SQLAdvisor是由美团点评公司技术工程部DBA团队(北京)开发维护的一个分析SQL给出索引优化建议的工具。它基于MySQL原生态词法解析,结合分析SQL中的where条件、聚合条件、多表Join关系 给出索引优化建议。目前SQLAdvisor在美团点评内部广泛应用,公司内部对SQLAdvisor的开发全面转到github上,开源和内部使用保持一致

QLite源码分析参考

https://huili.github.io/sqlite/sqliteintro.html

SQLite安全问题

将内容加密后再写入数据库

这种方式使用起来简单,在入库/出库的过程中只需要将字段做对应的加解密操作即可,一定程度上解决了将数据赤裸裸暴露的问题。但也有很大弊端:

  1. 这种方式并不是彻底的加密,还是可以通过数据库查看到表结构等信息。
  2. 对于数据库的数据,数据都是分散的,要对所有数据都进行加解密操作会严重影响性能。

对数据库文件加密

将整个数据库整个文件加密,这种方式基本上能解决数据库的信息安全问题。目前已有的SQLite加密基本都是通过这种方式实现的,常见的几种加密方式是 SQLite Encryption Extension (SEE) 事实上SQLite在设计之初是有暴露加解密接口,只是免费版本没有实现而已。而SQLite Encryption Extension (SEE)就是SQLite的加密版本,收费的

https://github.com/sqlcipher/sqlcipher

对于大部分开发者来说,兼顾安全性和成本的同时,免费版本的SQLCipher也是我们优先采取的安全性加固方案。

并发问题

SQLite 不支持并发

SQLiteDatabaseLockedException

上一篇下一篇

猜你喜欢

热点阅读