列表预取(PREFETCH='L'或'U')

列表预取读取由索引中的记录标识符(RID)列表确定的一组数据页。

开始特定程序编程接口信息。 列表预取访问路径非常适合查询,其中符合条件的行(由索引键序列确定)不是顺序的,而是跳序的,但比较稀疏,或者当DATAREPEATFACTORF统计值的值很大时。

使用列表预取功能,获取的数据页面不必连续。 单个列表预取中可检索的最大页数是32(实用程序为64)。 Db2 需要使用列表预取时,PREFETCH列的值设置为“L”或“U”。

列表预取可用于单次或多次索引访问。

当优化程序选择列表预取访问路径时, Db2 会使用以下流程:
  1. 通过匹配索引扫描一个或多个索引,检索行标识符列表。
  2. 按页码升序排列行标识符列表。
  3. 使用行标识符的排序列表,按顺序预取页面。

列表预取不会保留索引给出的数据排序。 由于在数据访问之前,RID按页码顺序排序,因此数据不会按任何列的顺序检索。 如果数据必须按“ORDER BY”子句或其他原因排序,则需要额外排序。 Db2 有时出于性能考虑,会使用列表预取而不对RID列表进行排序。 当这种情况发生时,PREFETCH列的值将设置为“U”。

在混合连接中,如果索引高度聚集,则访问数据之前可能不会对页码进行排序。

列表预取可与索引扫描的大多数匹配谓词一起使用。

当使用列表预取时

列表预取用于以下操作:

  • 通常只有一个索引,其集群比率低于80%
  • 有时,在集群比率较高的索引上,如果预计要访问的数据量太小,无法提高顺序预取的效率,但数据量又足够大,需要多次常规读取
  • 始终通过多重索引访问数据
  • 在混合连接期间,始终从内部表访问数据
  • 通常用于可更新的游标,当索引包含可能更新的列时。
  • 当IN列表谓词通过内存表作为匹配谓词(ACCESSTYPE='IN')使用时。
  • 有时,当更新索引键列时,UPDATE语句需要索引访问。 更多信息,请参阅 UPDATE和MERGE语句的索引访问

Db2 使用RID池进行列表预取处理。 MAXRBLK子系统参数用于控制RID池的最大容量。 如果单个列表预取操作试图使用过多的RID池或尝试从表中读取过多的行,访问路径可能会恢复为表空间扫描。 但是,您可以通过设置MAXTEMPS_RID子系统参数的值来指定RID列表处理继续在工作文件中。

列表预取的优势

当按顺序访问多个非连续数据页时,列表预取对于跳过顺序访问非常有用,但中间页不包含所需数据。 在这种情况下,动态预取会读取所有中间页面,异步读取的页面数量超过了获取页面操作的数量,缓冲池的使用效率低下。 与动态预取相比,列表预取具有以下具体优势:

  • 列表预取非常经济地使用缓冲区。
  • 列表预取对索引集群比例不敏感,当数据获取页面稀疏时,其性能比动态预取好得多。
  • 排序列表预取功能不会对同一数据页使用两次getpage操作。
  • 如果需要跳过多个数据页,列表预取可以缩短通道时间,在控制单元命中率较高的情况下,比动态预取更快。
  • 对于某些类型的控制单元,列表预取比顺序I/O的跳过顺序访问更快。 您可以咨询您的存储供应商,了解您的控制单元类型是否适用。

列表预取的缺点

然而,与动态预取相比,列表预取也有一定的缺点:

  • 当行标识符非常密集时,动态预取的性能要优于列表预取,例如当簇比很高时进行范围扫描。
  • 对于某些类型的控制单元,列表预取比顺序I/O的跳过顺序访问速度慢。 您可以咨询您的存储供应商,了解您的控制单元类型是否适用。
  • 对于使用索引键列的ORDER BY或GROUP BY子句的查询,列表预取总是需要对结果集进行排序,而动态预取则不一定需要排序。 排序的成本取决于结果集的大小,而不是读取的数据页的数量。
  • 如果应用程序在获取整个结果集之前过早关闭光标,则列表预取用于处理索引和创建排序RID列表的时间将被浪费。