PRAGMA auto_vacuum

1. SQLite Vacuum
       VACUUM命令通过复制主数据库中的内容到一个临时数据库文件,然后清空主数据库,并从副本中重新载入原始的数据库文件。这消除了空闲页,把表中的数据排列为连续的,另外会清理数据库文件结构。如果表中没有明确的整型主键(INTEGER PRIMARY KEY),VACUUM 命令可能会改变表中条目的行 ID(ROWID)。VACUUM 命令只适用于主数据库,附加的数据库文件是不可能使用 VACUUM 命令。如果有一个活动的事务,VACUUM 命令就会失败。VACUUM 命令是一个用于内存数据库的任何操作。由于 VACUUM 命令从头开始重新创建数据库文件,所以 VACUUM 也可以用于修改许多数据库特定的配置参数。

1.1 手动 VACUUM
1.1.1 在命令提示符中对整个数据库发出 VACUUM 命令的语法:
    $sqlite3 database_name "VACUUM;"
1.1.2 您也可以在 SQLite 提示符中运行 VACUUM,如下所示:
    sqlite> VACUUM;
1.1.3 您也可以在特定的表上运行 VACUUM,如下所示:
    sqlite> VACUUM table_name;
1.1.4 调用sqlite3_exe()数据库系统API:
    sqlte3_exe(..., "VACUUM table_name", ...);

2. Auto-VACUUM
2.1 SQLite 的 Auto-VACUUM 与 VACUUM 差异:

       Auto-VACUUM它只是把空闲页移到数据库末尾,从而减小数据库大小。通过这样做,它可以明显地把数据库碎片化,而 VACUUM 则是反碎片化。所以 Auto-VACUUM 只会让数据库更小---???

2.2 在 SQLite 提示符中,您可以通过下面的编译运行,启用/禁用 SQLite 的 Auto-VACUUM:
    sqlite> PRAGMA auto_vacuum = NONE;  -- 0 means disable auto vacuum
    sqlite> PRAGMA auto_vacuum = INCREMENTAL;  -- 1 means enable incremental vacuum
    sqlite> PRAGMA auto_vacuum = FULL;  -- 2 means enable full auto vacuum
    您可以从命令提示符中运行下面的命令来检查 auto-vacuum 设置:
        $sqlite3 database_name "PRAGMA auto_vacuum;"
        
3. 关于PRAGRM AUTO_VACUUM如何使用?
3.1 该命令的具体用法: 
    PRAGMA auto_vacuum = 0 或 NONE; 
    PRAGMA auto_vacuum = 1 或 FULL; 
    PRAGMA auto_vacuum = 2 或 INCREMENTAL; 
    备注:这里,0和NONE表示的含义相同。

3.2   AUTO_VACUUM命令详解:

PRAGMA auto_vacuum = 0 : AUTO_VACUUM命令缺省值为0,表示禁用AUTO_VACUUM。除非在编译的时候定义了宏SQLITE_DEFAULT_AUTOVACUUM。数据删除的时候,数据库大小不会改变。没用的数据库文件页面会被添加到freelist里头,用于将来重用。这时,使用VACUUM命令,可以重建整个数据库,以回收无用的磁盘空间。

PRAGMA auto_vacuum = 1: 所有的freelist页会被移动到文件末尾,每次事务提交的时候文件会被截短。注意,自动vacuum只是从文件是截断freelist页,并没有进行碎片重整等操作,也就是说,它没有VACUUM命令来得彻底。事实上,自动vacuum会让碎片更多。 只有在数据库存储某些附加信息的时候,它允许每个数据库页来跟踪它的引用页,自动vacuum才用得上。它必须在没有创建任何表的情况下启用。在一个表已经创建了之后,是不能启用和停用auto-vacuum的。 
PRAGMA auto_vacuum = 2: 表示增量vacuum,意味着并不是在每次提交事务的时候自动vacuum,需要调用一个独立的incremental_vacuum语句来触发auto-vacuum。 
        数据库可以在1和2两种vacuum模式下进行切换。但是不能从none到full或incremental间切换。要想切换,要么数据库是全新的数据库(没有任何表),或者单独运行vacuum命令以后。改变自动vacuum模式,首先执行auto_vacuum语句设置新的模式,然后调用VACUUM来重整数据库。 不带参数的auto_vacuum语句返回当前的auto_vacuum模式值。

4. 用例

4.1 新建数据库

char *pszSqliteName = USER_DATA_SQLITE3_PATH"gwooDb";
iRet = sqlite3_open(pszSqliteName, &db);
if (iRet)
{
	TRACE("can't open db!/n", sqlite3_errmsg(db));
	sqlite3_close(db);
}

4.2 新建数据库表

//建表
char *sqlCmd = "CREATE TABLE RealTable1(\
				StartTime TEXT(15),\
				SuccTime TEXT(15),\
				SaveTime TEXT(15),\
				MtrAddr	BLOB,\
				x20000200 BLOB,\
				x20010200 BLOB,\
				x20020200 BLOB)";
iRet = sqlite3_exec(db, sqlCmd, 0, 0, &errmsg);

4.3 新建数据库表索引

char *sql="CREATE INDEX RealTable1_INDEX ON RealTable1(StartTime, SuccTime, SaveTime, MtrAddr)";
iRet = sqlite3_exec(db, sql, 0, 0, &errmsg);

上面的数据库表在增加索引后会导致数据库文件的空间增大一倍,实际在使用时一定要注意!!!

4.4 设置PRAGRM AUTO_VACCUM=0

char *sql = "PRAGRAM auto_vacuum = 0";	
iRet = sqlite3_exec(db, sql, 0, 0, &errmsg);

4.5 增加事务接口

//描述:执行SQL命令
int ExecSqlCmd(sqlite3 *db, char *sql)
{
	int iRet;
	char *err_msg = 0;
	char buf[1024];

	if ((iRet = sqlite3_exec(db, sql, NULL, 0, &err_msg)) != SQLITE_OK)
		sqlite3_free(err_msg);

	memset(buf, 0, sizeof(buf));
	sprintf(buf, "Exec sql: \"%s\", code:%d\n", sql, iRet);
	TRACE("%s", buf);

	return iRet;
}

//描述:开始事务处理
void BeginTransaction(sqlite3 *db)
{
	ExecSqlCmd(db, "BEGIN TRANSACTION");
}


//描述:结束事务处理
void CommitTransaction(sqlite3 *db)
{
	ExecSqlCmd(db, "COMMIT");
}


//描述:回滚事务处理
void RollBackTransaction(sqlite3 *db)
{
	ExecSqlCmd(db, "ROLLBACK");
}

4.6 增加SQL执行时间打印(毫秒级别)

void StartTestSqliteTime()
{
	TMillTime tMillTime;
	char  cStr[32];
	WORD wStrLen;

	memset(cStr, 0, sizeof(cStr));
	GetCurMillTime(&tMillTime);
	MillTimeToStr(tMillTime, cStr);
	TRACE("Start test time=%s.\n", cStr);
}

void FinishTestSqliteTime()
{
	TMillTime tMillTime;
	char  cStr[32];
	WORD wStrLen;

	memset(cStr, 0, sizeof(cStr));
	GetCurMillTime(&tMillTime);
	MillTimeToStr(tMillTime, cStr);
	TRACE("Finish test time=%s.\n", cStr);
}

4.7 添加10万条记录

StartTestSqliteTime();
BeginTransaction(db);
for (int i=0; i<100000; i++)
{
    char *insertData2 = "INSERT INTO RealTable1(StartTime, SuccTime, SaveTime, MtrAddr, x20020200) VALUES(\"20190104095030\", \"20190105095031\", \"20190105095030\", \"222222222222\", \"222222222222222222222222\")";
    iRet = sqlite3_exec(db, insertData2, 0, 0, &errmsg);
    //char *insertData3 = "INSERT INTO RealTable1 VALUES(\"20190106095030\", \"20190106095031\", \"20190106095030\", \"333333333333\", \"3333333333333333333\", \"444444444444444444\", \"55555555555555555\")";
    //iRet = sqlite3_exec(db, insertData3, 0, 0, &errmsg);
}
CommitTransaction(db);
FinishTestSqliteTime();

4.8 删除部分记录

BeginTransaction(db);
char *sql = "DELETE FROM RealTable1 WHERE StartTime=\"20190104095030\"";	
iRet = sqlite3_exec(db, sql, 0, 0, &errmsg);
CommitTransaction(db);
//RollBackTransaction(db);

4.9 删除数据库表

BeginTransaction(db);
char *sql = "DROP TABLE RealTable1";	
iRet = sqlite3_exec(db, sql, 0, 0, &errmsg);
CommitTransaction(db);
//RollBackTransaction(db);

4.10 设置VACCUM,释放数据库文件空间

char *sql = "vacuum";	
iRet = sqlite3_exec(db, sql, 0, 0, &errmsg);

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值