1. 程式人生 > >SQLite的VACUUM命令

SQLite的VACUUM命令

PRAGMA auto_vacuum

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。
PRAGMA auto_vacuum;
PRAGMA auto_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會造成而額外的檔案碎片。