索引预提取概览

AlloyDB for PostgreSQL 使用索引预提取来加快通过 B 树索引读取一系列行的查询。默认情况下,在运行 PostgreSQL 17 及更高版本的 AlloyDB 和 AlloyDB Omni 实例上,索引预提取功能处于启用状态。您无需设置任何标志、重建索引或更改应用或 SQL 查询,即可从中受益。

索引预提取的工作原理

当查询通过索引扫描一系列值(例如,索引列上的 BETWEEN 谓词或 ORDER BY ... LIMIT 子句)时,扫描会读取索引页和索引条目指向的表页。这些表页通常分散在存储空间中。在标准 PostgreSQL 中,扫描会一次读取这些页面,因此当页面尚未在内存中时,查询会花费大部分时间等待存储 I/O。

借助索引预提取,AlloyDB 会在索引和表上提前查看正在运行的扫描,并并行读取扫描即将需要的页面。AlloyDB 会将预提取的页面暂存在实例的本地 SSD 缓存中,以便在扫描请求页面时,从快速本地存储(而非远程存储)提供该页面。预提取的页面会暂存在 PostgreSQL 共享缓冲区之外,因此预提取不会减少其他会话可用的缓冲区缓存。

索引预提取包含以下保护措施,因此不会给无法从中受益的查询增加开销:

  • 预提取会在 LIMIT 子句的边界处停止,因此扫描不会读取查询返回的行之外的页面。
  • 对于覆盖索引上的纯索引扫描,AlloyDB 仅预提取索引页,不读取表页。
  • 返回单行的查询(例如主键查找)不会触发预提取。

工作负载优势

当工作集大于实例的内存,并且查询通过 B 树索引读取多行时,索引预提取最有用。以下是受益查询的示例:

  • 对已编入索引的时间戳、日期或数值列进行范围查询,例如针对某个时间范围生成报告。
  • 为单个键返回多行的查询,例如客户的订单记录。
  • 内侧为返回多行的索引扫描的联接。
  • 从面向行的表中读取大范围数据的分析查询。

对于数据已在共享缓冲区中的查询以及单行查找,无论是否进行预提取,其性能都相同。

执行计划中的预提取

如需查看索引预提取对查询的影响,请使用 EXPLAIN (ANALYZE, BUFFERS) 运行查询。预提取加载到本地 SSD 缓存中的页面在计划的索引扫描节点上显示为 ultra fast cache hit 计数。如需详细了解如何读取这些计数器,请参阅获取和分析执行计划。

后续步骤