热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

sqlite3数据库优化处理

1、sqlite删除数据或者表后,文件大小不变原因分析:sqlite采用的是变长纪录存储,当你从Sqlite删除数据后,未使用的磁盘空间被添加到一个内在
1、sqlite删除数据或者表后,文件大小不变

原因分析:

sqlite采用的是变长纪录存储,当你从Sqlite删除数据后,未使用的磁盘空间被添加到一个内在的”空闲列表”中用于存储你下次插入的数据,用于提高效率,磁盘空间并没有丢失,但也不向操作系统返回磁盘空间,这就导致删除数据乃至清空整个数据库后,数据文件大小还是没有任何变化,还是很大


解决办法:

sqlite3中执行vacuum命令即可。


[zhaojq@virtual-machine]# ls -shal sqldata.s3db      
83M -rw-r--r-- 1 kt kt 83M  4月  1 16:11 sqldata.s3db


//从Sqlite删除数据

[zhaojq@virtual-machine]# sqlite3 sqldata.s3db 
SQLite version 3.8.2 2013-12-06 14:53:30
Enter ".help" for instructions
Enter SQL statements terminated with a ";" 
sqlite> delete from records;
sqlite> .quit


//数据库大小没有发生变化
[zhaojq@virtual-machine]# ls -shal sqldata.s3db
83M -rw-r--r-- 1 kt kt 83M  4月  5 14:40 sqldata.s3db


[zhaojq@virtual-machine]# sqlite3 sqldata.s3db 
sqlite> vacuum;
sqlite> .quit


//数据库大小发生变化
[zhaojq@virtual-machine]# ls -shal sqldata.s3db
28K -rw-r--r-- 1 kt kt 25K  4月  5 14:48 sqldata.s3db


以下译文转自:http://blog.csdn.net/liukang325/article/details/23422335

The VACUUM command rebuilds the entire database. There are several reasons an application might do this:

1. Unless SQLite is running in “auto_vacuum=FULL” mode, when a large amount of data is deleted from the database file it leaves behind empty space, or “free” database pages. This means the database file might be larger than strictly necessary. Running VACUUM to rebuild the database reclaims this space and reduces the size of the database file.

(译文:除非SQLite运行在“auto_vacuum=FULL”模式,否则当从数据库文件中删除大量数据之后,就会留下很多空白空间,或者“空闲”的数据库页。这意味着数据库文件的大小会比(它所存储的数据)实际需要的(空间)更大。运行VACUUM命令将会重新构建数据库文件,回收空白空间,减小数据库文件的大小。)

2. Frequent inserts, updates, and deletes can cause the database file to become fragmented – where data for a single table or index is scattered around the database file. Running VACUUM ensures that each table and index is largely stored contiguously within the database file. In some cases, VACUUM may also reduce the number of partially filled pages in the database, reducing the size of the database file further.

(译文:频繁的插入,更新和删除操作,会导致数据库文件变得支离破碎(产生大量的内存碎片)——因为单独一个表中的数据或者索引可能会分散的存储在数据库文件中。运行VACUUM命令可以确保每个表(的数据)和索引可以最大限度的连续存储在数据库文件中。在某些情况下,VACUUM命令也会减少数据库中的一部分填充页面,从而进一步减小数据库文件的大小。)

3. Normally, the database page_size and whether or not the database supports auto_vacuum must be configured before the database file is actually created. However, when not in write-ahead log mode, the page_size and/or auto_vacuum properties of an existing database may be changed by using the page_size and/or pragma auto_vacuum pragmas and then immediately VACUUMing the database. When in write-ahead log mode, only the auto_vacuum support property can be changed using VACUUM.

(译文:通常情况下,数据库的page_size和数据库是否支持auto_vacuum(这些配置)都要在数据库文件实际创建之前进行配置。然而,如果SQLite不是运行在“写前日志(write-ahead log)”模式下,一个已经存在(已经创建)的数据库(文件)的page_size和/或auto_vacuum属性,可以使用page_size和/或auto_vacuum编译指示进行修改,然后立即清扫数据库。如果SQLite是运行在“写前日志”模式下,则只有(是否支持)auto_vacuum属性可以通过VACUUM命令进行修改。)

VACUUM only works on the main database. It is not possible to VACUUM an attached database file.

(译文:VACUUM命令只能工作在主数据库上,不能用来“清扫”一个附加的数据库文件。)

The VACUUM command works by copying the contents of the database into a temporary database file and then overwriting the original with the contents of the temporary file. When overwriting the original, a rollback journal or write-ahead log WAL file is used just as it would be for any other database transaction. This means that when VACUUMing a database, as much as twice the size of the original database file is required in free disk space.

(译文:VACUUM命令通过如下方式进行工作:首先把数据库内容复制到一个临时数据库文件中,然后再把临时数据库文件中的内容写回到原始数据库文件中(以整理数据库文件)。当将内容重新写回到原始数据库文件时,一个回滚日志或者写前日志WAL文件将会被使用,正如它为其它数据库事务服务一样。这意味着当“清扫”一个数据库时,将需要使用高达两倍于原始数据库文件大小的空闲磁盘空间。)

The VACUUM command may change the ROWIDs of entries in any tables that do not have an explicit INTEGER PRIMARY KEY.

(译文:VACUUM命令可能会改变数据库表的行ID(ROWIDs),假如这个表没有一个显示的整形主键(INTEGER PRIMARY KEY)的话。)

A VACUUM will fail if there is an open transaction, or if there are one or more active SQL statements when it is run.

(译文:如果存在一个打开(open)的事务,或者存在一个或多个正在活动(活跃)的(active)SQL语句,那么VACUUM命令将会执行失败。)

As of SQLite version 3.1, an alternative to using the VACUUM command to reclaim space after data has been deleted is auto-vacuum mode, enabled using the auto_vacuum pragma. When auto_vacuum is enabled for a database free pages may be reclaimed after deleting data, causing the file to shrink, without rebuilding the entire database using VACUUM. However, using auto_vacuum can lead to extra database file fragmentation. And auto_vacuum does not compact partially filled pages of the database as VACUUM does.

(译文:对于SQLite3.1,可以使用“auto-vacuum模式”代替“VACUUM命令”在删除数据后回收空间,可以通过使用auto_vacuum编译指示来使能auto-vacuum模式。使能auto_vacuum模式之后,一个数据库在删除数据后留下的空闲页就可能会被回收,从而缩小数据库文件,而不用使用VACUUM命令重新构建整个数据库。然而,使用auto_vacuum模式将会导致额外的数据库文件碎片。并且使用auto_vacuum模式不会压缩部分数据库的填充页而VACUUM命令则会(压缩)。)

上面的内容来自SQLite官网:http://www.sqlite.org/lang_vacuum.html,下面做些补充:

(1)VACUUM命令是SQLite的一个扩展功能,模仿PostgreSQL中的相同命令而来。在SQLite早期版本中,若调用VACUUM带一个表名或索引名,则将整理该表或索引。后来VACUUM被重新实现,索引名或表名被忽略。

当数据库中的一个对象(表,索引或触发器)被撤销,会留下空白的空间。它使数据库比需要的大小更大,但能加快插入速度。实时的插入和删除会使得数据库文件结构混乱,减慢对数据库内容访问的速度。VACUUM命令复制主数据库文件到临时数据库并从临时数据库重新载入到主数据库,以整理数据库文件。这将除去空白页,使表数据彼此相邻排列,并整理数据库文件结构。不能对附加数据库文件进行以上操作。

若当前有活动事务,该命令无法起作用。对于in-memory数据库,该命令无效。在SQLite3.1中,可以通过使用auto-vacuum模式作为VACUUM命令的一个替代,使用 auto_vacuum pragma开启该模式。

(2)使用VACUUM命令可以在删除数据后使数据库文件减小,在SQLIte3以后有一个替代的办法是使用PRAGMA auto_vacuum。

12 PRAGMAauto_vacuum;PRAGMAauto_vacuum =0|1;

查询或设置数据库的auto-vacuum标记。

正常情况下,当提交一个从数据库中删除数据的事务时,数据库文件不改变大小。未使用的文件页被标记并在以后的添加操作中再次使用。这种情况下使用VACUUM命令释放删除后留下的空白空间。

当开启auto-vacuum,并提交一个从数据库中删除数据的事务时,数据库文件自动收缩,(VACUUM命令在auto-vacuum开启的数据库中不起作用)。数据库会在内部存储一些信息以便支持这一功能,这使得数据库文件比不开启该选项时稍微大一些。

另外,“auto-vacuuming must be turned on before any tables are created. It is not possible to enable or disable auto-vacuum after a table has been created”。大概意思是,当有表创建后就不能对auto-vacuum进行更改。

使用auto_vacuum仅仅是将空闲的页除去,并不会像VACUUM那样对数据库进行碎片整理,或是压缩数据库页。使用auto_vacuum会造成而额外的文件碎片。


2、SQLite3中自增主键归零 [zhaojq@virtual-machine]# sqlite3 sqldata.s3db 
sqlite>delete from 'TABLENAME'
sqlite>update sqlite_sequence set seq=0 where name='TABLENAME';


推荐阅读
author-avatar
__wolf狼
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有