Small. Fast. Reliable.
Choose any three.
DBSTAT虚拟表

1.概述

DBSTAT虚拟表是一个只读的同义虚拟表,它返回有关用于存储SQLite数据库内容的磁盘空间量的信息。DBSTAT虚拟表的示例用例包括sqlite3_analyzer.exe 实用程序和由Fossil实现的SQLite版本控制系统中的 表大小饼图

使用SQLITE_ENABLE_DBSTAT_VTAB编译时选项构建SQLite时 ,DBSTAT虚拟表在所有数据库连接上均可 用 。

DBSTAT虚拟表是一个同义的虚拟表,这意味着在使用它之前,不必运行CREATE VIRTUAL TABLE来创建dbstat虚拟表的实例。可以使用“ dbstat”模块名称作为直接查询dbstat虚拟表的表名称。例如:

选择* FROM dbstat;

如果需要使用dbstat模块的命名虚拟表,则建议的创建dbstat虚拟表实例的方法如下:

使用dbstat(main)创建虚拟表temp.stat;

注意“温度”。虚拟表名称(“ stat”)之前的限定符。此限定符使虚拟表成为临时表-仅在当前数据库连接期间存在。这是推荐的方法。

dbstat的“ main”参数是要为其提供信息的默认模式。默认值为“ main”,因此在上面的示例中使用“ main”是多余的。对于任何特定的查询,可以通过在查询的FROM子句中将备用模式指定为虚拟表名称的函数参数来更改模式。(有关更多详细信息,请参见FROM子句中表值函数的进一步讨论 。)

DBSTAT虚拟表的架构如下所示:

创建表dbstat(
  名称TEXT-表或索引的名称
  路径TEXT,-从根目录到页面的路径
  pageno INTEGER,-页码或页数
  pagetype TEXT,-'internal','leaf','overflow'或NULL
  ncell INTEGER,-页上的单元格(溢出页为0)
  有效载荷INTEGER,-此页面或btree上的有效载荷字节
  未使用的INTEGER,-此页面或btree上未使用空间的字节数
  mx_payload INTEGER,-此行中所有单元格的最大有效负载大小
  pgoffset INTEGER,-数据库文件中页面的字节偏移
  pgsize INTEGER,-页面大小,以字节为单位
  模式TEXT HIDDEN,-正在分析的数据库模式
  Aggregation BOOL HIDDEN-真,启用聚合模式
);

DBSTAT表仅报告数据库文件中btree的内容。分析中省略了自由列表页,指针映射页和锁定页。

缺省情况下,DBSTAT表中数据库文件的每个btree页面只有一行。每一行都提供有关该数据库一页的空间利用率的信息。但是,如果隐藏列“ aggregate”为TRUE,则结果将被汇总,并且数据库中每个btree的DBSTAT表中只有一行,从而提供了有关整个btree的空间利用率的信息。

2. dbstat虚拟表的“路径”列

“路径”列描述了从btree结构的根节点到每个页面的路径。根节点本身的“路径”为“ /”。当“ aggregate”为TRUE时,“ path”为NULL。btree页面根目录的最左侧子页面的“路径”为“ / 000 /”。(树按从左到右的顺序存储内容,因此左页面的键比右页面的键小。)根页面的最靠左的子级是'/ 001',依此类推,每个同级页面由3位数的十六进制值标识。第451个最左侧兄弟姐妹的子级具有诸如'/ 1c2 / 000 /,'/ 1c2 / 001 /'等的路径。溢出页面通过在路径上附加一个'+'字符和一个六位数的十六进制值来指定链接到它们所链接的单元格。例如,

'/ 1c2 / 000 + 000000'//溢出链中的第一页
'/ 1c2 / 000 + 000001'//溢出链中的第二页
'/ 1c2 / 000 + 000002'//溢出链中的第三页

如果使用BINARY排序顺序对路径进行排序,则与单元格关联的溢出页面将在排序顺序中早于其子页面出现:

'/ 1c2 / 000 /'//根的第451个孩子的最左孩子

3.汇总数据

从SQLite版本3.31.0(2020-01-22)开始,DBSTAT表具有一个名为“ aggregate”的新隐藏列,如果将其约束为TRUE,则它将导致DBSTAT在数据库中每btree生成一行,而不是一行每页行。在聚合模式下运行时,“ path”,“ pagetype”和“ pgoffset”列始终为NULL,而“ pageno”列保存整个btree中的页面数,而不是对应于btree的页面数。排。

下表显示了普通模式和聚合模式下DBSTAT的(非隐藏)列的含义:

柱子 正常意义 聚合模式含义
名称 由当前行的btree实现的表或索引的名称
小路 上面的描述 始终为NULL
页面编号 当前行的数据库页面的页面号 当前行中btree中的总页数
页面类型 “叶子”或“内部” 始终为NULL
单元 当前页面或btree上的单元格数
有效载荷 当前页面或btree上有用负载的字节数
没用过 当前页或btree上未使用的字节
mx_payload 当前页面或btree中任何位置找到的最大有效负载。
pgoffset 到页面开头的字节偏移量 始终为NULL
pg大小 当前页面或btree使用的总存储空间。

4. dbstat虚拟表的示例用法

要查找用于在模式“ aux1”中存储表“ xyz”的页面总数,请使用以下两个查询之一(第一个是传统方式,第二个显示了聚合功能的使用):

SELECT count(*)FROM dbstat('aux1')WHERE name ='xyz';
SELECT pageno FROM dbstat('aux1',1)WHERE name ='xyz';

若要查看表内容在磁盘上的存储效率,请计算用于保存实际内容的空间量除以所使用的磁盘空间总量。该数字越接近100%,包装效率越高。(在此示例中,假设“ xyz”表位于“主”模式中。同样,有两个不同的版本分别显示了使用DBSTAT的情况(不具有和具有新的聚合功能)。)

从dbstat WHERE name ='xyz'中选择sum(pgsize-未使用)* 100.0 / sum(pgsize);
SELECT(pgsize-unused)* 100.0 / pgsize from dbstat
 WHERE名称='xyz'AND聚合= TRUE;

要查找表的平均扇出,请运行:

从dbstat那里选择avg(ncell)name ='xyz'AND pagetype ='internal';

当磁盘访问是顺序访问时,现代文件系统运行得更快。因此,如果数据库文件的内容位于连续页面上,SQLite将运行得更快。要找出数据库中哪些页面是连续的(从而获得一种度量值,这对于确定何时使用VACUUM可能有用),请运行如下查询:

CREATE TEMP TABLE s(行整数主键,pageno INT);
插入s(pageno)SELECT pageno FROM dbstat ORDER BY路径;
选择总和(s1.pageno + 1 == s2.pageno)* 1.0 / count(*)
  从s AS s1,s AS s2
 其中s1.rowid + 1 = s2.rowid;
DROP TABLE s;