在线文档教程

ANALYZE

SQL As Understood By SQLite

[Top]

ANALYZE

analyze-stmt: hide

ANALYZE 命令收集有关表和索引的统计信息,并将收集的信息存储在数据库的内部表中,查询优化器可以访问信息并使用它来帮助做出更好的查询计划选择。如果没有给出参数,则分析所有附加的数据库。如果模式名称作为参数给出,则分析该数据库中的所有表和索引。如果参数是一个表名,那么只分析该表和与该表相关的索引。如果参数是索引名称,那么只分析那一个索引。

默认实现将所有统计信息存储在名为“sqlite_stat1”的单个表中。如果使用 SQLITE_ENABLE_STAT3 选项编译 SQLite ,并且没有 SQLITE_ENABLE_STAT4 选项,则会收集附加的直方图数据并将其存储在 sqlite_stat3中。如果使用 SQLITE_ENABLE_STAT4 选项编译 SQLite ,则会收集其他直方图数据并将其存储在 sqlite_stat4 中。旧版本的 SQLite 在使用 SQLITE_ENABLE_STAT2 编译时会使用 sqlite_stat2 表,但所有最新版本的 SQLite 都会忽略 sqlite_stat2 表。未来的增强可能会创建具有相同名称模式的其他内部表格,除了最后一位数字大于“4”。所有这些表格统称为“statistics tables”。

统计表的内容可以使用 SELECT 进行查询,并且可以使用 DELETE ,INSERT 和 UPDATE 命令进行更改。DROP TABLE 命令适用于 SQLite 版本3.7.9以来的统计信息表。(2011-11-01)ALTER TABLE 命令不适用于统计表。在更改统计表内容时应该使用适当的谨慎措施,因为无效内容可能导致 SQLite 选择低效的查询计划。一般来说,除了调用 ANALYZE 命令之外,不应该通过任何机制修改统计表的内容。有关更多信息,请参阅“使用 SQLITE_STAT 表手动控制查询计划”。

ANALYZE 收集的统计信息不会随着数据库内容的变化而自动更新。如果数据库内容发生重大变化,或者数据库模式发生变化,则应考虑重新运行 ANALYZE 命令以更新统计信息。

查询计划程序在读取模式时将统计信息表的内容加载到内存中。因此,当应用程序直接更改统计表时,SQLite 不会立即注意到这些更改。应用程序可以通过运行 ANALYZE sqlite_master 来强制查询计划程序重新读取统计信息表。

自动运行 ANALYZE

PRAGMA optimize 命令将根据需要自动在单个表上运行 ANALYZE 。推荐的做法是让应用程序在关闭每个数据库连接之前调用 PRAGMA 优化语句。

每个 SQLite 数据库连接都会记录查询计划者将从手头获得精确结果的 ANALYZE 时受益的情况。这些记录保存在内存中并在数据库连接的整个生命周期内累积。PRAGMA optimize 命令查看这些记录,并仅对那些新的或更新的 ANALYZE 数据似乎可能有用的表运行 ANALYZE 。在大多数情况下,PRAGMA 优化不会运行 ANALYZE ,但它偶尔会对之前从未分析过的表或者上次分析后显着增长的表进行分析。

由于 PRAGMA 优化的操作在一定程度上由在同一数据库连接上评估的先前查询确定,因此建议将 PRAGMA 优化推迟到数据库连接关闭并因此有机会积累必要的使用信息尽可能。对于长时间保持打开状态的数据库连接,每隔几个小时或每几天设置一个计时器来运行 PRAGMA 优化也是合理的。

需要更多控制的应用程序可以运行 PRAGMA 优化(0x03)以获取 SQLite 认为适合运行的 ANALYZE 命令的列表,但不实际运行这些命令。如果返回的集合非空,那么应用程序可以决定是否运行建议的 ANALYZE 命令,也许在提示用户提供指导之后。

PRAGMA 优化命令最初是在 SQLite 3.18.0(2017-03-28)中引入的,并且不适用于所有以前版本的 SQLite 。

预期的未来增强

所有现有版本的 SQLite 都对 ANALYZE 进行全表扫描。对于多 GB 和更大的数据库,这可能会很慢。未来版本的 SQLite 可能使用随机抽样而不是全表扫描来获取数据库形状的估计值,尤其是在较大的表上。结果将近似,但会足够接近查询计划目的。截至2017-03-20,这个概念已经在实验分支中进行了测试,似乎运行良好,但尚未折叠成正式版本。