DBSTAT 虚拟表是一个只读 同名虚拟表,它返回有关 SQLite 数据库内容所用磁盘空间的信息。DBSTAT 虚拟表的用例包括 sqlite3_analyzer.exe 实用程序以及 SQLite 的 Fossil 实现版本控制系统中的表格大小饼状图。
当 SQLite 使用 SQLITE_ENABLE_DBSTAT_VTAB 编译时选项构建时,DBSTAT 虚拟表在所有 数据库连接 上可用。
DBSTAT 虚拟表是一个 同名虚拟表,这意味着在使用它之前,无需运行 CREATE VIRTUAL TABLE 来创建 dbstat 虚拟表的实例。可以使用“dbstat”模块名称,就像它是一个表名一样,直接查询 dbstat 虚拟表。例如
SELECT * FROM dbstat;
如果需要使用 dbstat 模块的命名虚拟表,那么创建 dbstat 虚拟表实例的推荐方法如下
CREATE VIRTUAL TABLE temp.stat USING dbstat(main);
请注意虚拟表名称 (“stat”) 之前的“temp.”限定符。此限定符导致虚拟表成为临时表 - 仅在当前数据库连接的持续时间内存在。这是推荐的方法。
dbstat 的“main”参数是提供信息的默认模式。默认值为“main”,因此上述示例中使用“main”是多余的。对于任何特定查询,可以通过在查询的 FROM 子句中将备用模式指定为虚拟表名称的函数参数来更改模式。(有关更多详细信息,请参见 FROM 子句中的表值函数 的进一步讨论。)
DBSTAT 虚拟表的模式如下所示
CREATE TABLE dbstat( name TEXT, -- Name of table or index path TEXT, -- Path to page from root pageno INTEGER, -- Page number, or page count pagetype TEXT, -- 'internal', 'leaf', 'overflow', or NULL ncell INTEGER, -- Cells on page (0 for overflow pages) payload INTEGER, -- Bytes of payload on this page or btree unused INTEGER, -- Bytes of unused space on this page or btree mx_payload INTEGER, -- Largest payload size of all cells on this row pgoffset INTEGER, -- Byte offset of the page in the database file pgsize INTEGER, -- Size of the page, in bytes schema TEXT HIDDEN, -- Database schema being analyzed aggregate BOOL HIDDEN -- True to enable aggregate mode );
DBSTAT 表仅报告数据库文件内 btree 的内容。分析中省略了空闲列表页、指针映射页和锁页。
默认情况下,DBSTAT 表中每页数据库文件都有一个 btree 页面,每行提供有关该数据库页面空间利用率的信息。但是,如果隐藏列“aggregate”为 TRUE,则会汇总结果,并且 DBSTAT 表中每页数据库只有一个 btree,提供有关整个 btree 空间利用率的信息。
“path”列描述从 btree 结构的根节点到每个页面的路径。“path”本身的根节点为“/”。当“aggregate”为 TRUE 时,“path”为 NULL。btree 页面根节点最左侧子页面的“path”为“/000/”。(btree 按从左到右的顺序存储内容,因此左侧的页面比右侧的页面具有更小的键。)根页面左侧的下一个子页面为“/001”,依此类推,每个兄弟页面都由一个 3 位十六进制值标识。第 451 个左侧兄弟的子页面具有路径,例如“/1c2/000/”、“/1c2/001/”等。溢出页面通过将“+”字符和一个六位十六进制值附加到它们链接到的单元格的路径来指定。例如,链接自根页面第 450 个子节点最左侧单元格的链中的三个溢出页面由以下路径标识
'/1c2/000+000000' // First page in overflow chain '/1c2/000+000001' // Second page in overflow chain '/1c2/000+000002' // Third page in overflow chain
如果使用 BINARY 排序规则对路径进行排序,则与单元格关联的溢出页面将出现在排序顺序中与其子页面之前。
'/1c2/000/' // Left-most child of 451st child of root
从 SQLite 版本 3.31.0(2020 年 1 月 22 日)开始,DBSTAT 表新增了一个 隐藏列,名为“aggregate”,如果将其约束为 TRUE,则 DBSTAT 将为数据库中的每个 btree 生成一行,而不是每个页面一行。在聚合模式下运行时,“path”、“pagetype”和“pgoffset”列始终为 NULL,而“pageno”列包含整个 btree 中的页面数,而不是对应于该行的页面的页码。
下表显示了 DBSTAT 在正常模式和聚合模式下的(非隐藏)列的含义。
列 正常含义 聚合模式含义 name 当前行 btree 所实现的表或索引的名称 path 请参见 上文描述 始终为 NULL pageno 当前行数据库页面的页码 当前行 btree 中的总页数 pagetype 'leaf' 或 'interior' 始终为 NULL ncell 当前页面或 btree 上的单元格数 payload 当前页面或 btree 上的有效负载字节 unused 当前页面或 btree 上未使用的字节 mx_payload 在当前页面或 btree 中找到的最大有效负载。 pgoffset 页面的起始字节偏移量 始终为 NULL pgsize 当前页面或 btree 使用的总存储空间。
要查找用于存储模式“aux1”中表“xyz”的总页面数,请使用以下两个查询中的任何一个(第一个是传统方法,第二个显示聚合功能的使用)
SELECT count(*) FROM dbstat('aux1') WHERE name='xyz'; SELECT pageno FROM dbstat('aux1',1) WHERE name='xyz';
要查看表内容在磁盘上的存储效率,请计算用于保存实际内容的空间量除以使用的总磁盘空间量。此数字越接近 100%,填充效率越高。(在此示例中,假设“xyz”表位于“main”模式中。同样,有两个不同的版本显示了在分别使用和不使用新聚合功能的情况下使用 DBSTAT。)
SELECT sum(pgsize-unused)*100.0/sum(pgsize) FROM dbstat WHERE name='xyz'; SELECT (pgsize-unused)*100.0/pgsize FROM dbstat WHERE name='xyz' AND aggregate=TRUE;
要查找表的平均扇出,请运行以下命令
SELECT avg(ncell) FROM dbstat WHERE name='xyz' AND pagetype='internal';
现代文件系统在进行顺序磁盘访问时运行速度更快。因此,如果数据库文件的内容位于顺序页面上,SQLite 将运行得更快。要找出数据库中哪些页面是顺序页面(并因此获得一个测量值,该测量值可能有助于确定何时进行 VACUUM 操作),请运行以下查询
CREATE TEMP TABLE s(rowid INTEGER PRIMARY KEY, pageno INT); INSERT INTO s(pageno) SELECT pageno FROM dbstat ORDER BY path; SELECT sum(s1.pageno+1==s2.pageno)*1.0/count(*) FROM s AS s1, s AS s2 WHERE s1.rowid+1=s2.rowid; DROP TABLE s;
此页面上次修改于 2022 年 1 月 8 日 05:02:57 UTC