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的空间利用率的信息。
“路径”列描述了从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个孩子的最左孩子
从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使用的总存储空间。
要查找用于在模式“ 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;