Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16

20.7. 查询规划 #

20.7.1. 规划器方法配置
20.7.2. 规划器成本常量
20.7.3. 遗传查询优化器
20.7.4. 其他规划器选项

20.7.1. 规划器方法配置 #

这些配置参数提供了一种粗糙的方法来影响查询优化器选择的查询计划。如果优化器为特定查询选择的默认计划不是最佳计划,一个临时解决方案是使用其中一个配置参数来强制优化器选择不同的计划。提高优化器选择的计划质量的更好方法包括调整规划器成本常量(参见第 20.7.2 节),手动运行ANALYZE,增加default_statistics_target配置参数的值,以及使用ALTER TABLE SET STATISTICS增加为特定列收集的统计信息量。

enable_async_append (boolean) #

启用或禁用查询规划器使用异步感知追加计划类型。默认值为on

enable_bitmapscan (boolean) #

启用或禁用查询规划器使用位图扫描计划类型。默认值为 on

enable_gathermerge (boolean) #

启用或禁用查询规划器使用收集合并计划类型。默认值为 on

enable_hashagg (boolean) #

启用或禁用查询规划器使用哈希聚合计划类型。默认值为 on

enable_hashjoin (boolean) #

启用或禁用查询规划器使用哈希连接计划类型。默认值为 on

enable_incremental_sort (boolean) #

启用或禁用查询规划器使用增量排序步骤。默认值为 on

enable_indexscan (boolean) #

启用或禁用查询规划器使用索引扫描计划类型。默认值为 on

enable_indexonlyscan (boolean) #

启用或禁用查询规划器使用仅索引扫描计划类型(请参阅 第 11.9 节)。默认值为 on

enable_material (boolean) #

启用或禁用查询规划器使用物化。不可能完全禁止物化,但关闭此变量可以防止规划器插入物化节点,除非在正确性要求的情况下。默认值为 on

enable_memoize (boolean) #

启用或禁用查询规划器使用备忘计划,以缓存嵌套循环联接中参数化扫描的结果。当当前参数的结果已在缓存中时,此计划类型允许跳过对基础计划的扫描。当新条目需要更多空间时,可能从缓存中驱逐不太常用的查找结果。默认值为 on

enable_mergejoin (boolean) #

启用或禁用查询规划器使用合并联接计划类型。默认值为 on

enable_nestloop (boolean) #

启用或禁用查询规划器使用嵌套循环联接计划。不可能完全禁止嵌套循环联接,但关闭此变量会阻止规划器在有其他可用方法时使用嵌套循环联接。默认值为 on

enable_parallel_append (boolean) #

启用或禁用查询规划器使用并行追加计划类型。默认值为 on

enable_parallel_hash (boolean) #

启用或禁用查询规划器使用带有并行哈希的哈希联接计划类型。如果未启用哈希联接计划,则不产生任何效果。默认值为 on

enable_partition_pruning (boolean) #

启用或禁用查询计划程序从查询计划中消除分区表的 partition 的功能。这还控制计划程序生成查询计划的功能,该计划允许查询执行器在查询执行期间删除(忽略)partition。默认值为 on。有关详细信息,请参阅 第 5.11.4 节

enable_partitionwise_join (boolean) #

启用或禁用查询计划程序使用按分区连接,该连接允许通过连接匹配的 partition 来执行分区表之间的连接。按分区连接当前仅适用于连接条件包含所有分区键的情况,这些分区键必须具有相同的数据类型,并且具有成对匹配的子分区集。由于按分区连接规划在规划期间可能使用大量 CPU 时间和内存,因此默认值为 off

enable_partitionwise_aggregate (boolean) #

启用或禁用查询计划程序使用按分区分组或聚合,该分组或聚合允许对分区表进行分组或聚合,并针对每个分区分别执行。如果 GROUP BY 子句不包含分区键,则只能针对每个分区执行部分聚合,并且必须稍后执行最终化。由于按分区分组或聚合在规划期间可能使用大量 CPU 时间和内存,因此默认值为 off

enable_presorted_aggregate (boolean) #

控制查询计划程序是否会生成一个计划,该计划将提供按查询的 ORDER BY / DISTINCT 聚合函数所需的顺序预先排序的行。禁用后,查询计划程序将生成一个计划,该计划始终要求执行器在执行包含 ORDER BYDISTINCT 子句的每个聚合函数的聚合之前执行排序。启用后,计划程序将尝试生成一个更有效的计划,该计划为聚合函数提供按聚合所需的顺序预先排序的输入。默认值为 on

enable_seqscan (boolean) #

启用或禁用查询计划程序使用顺序扫描计划类型。完全禁止顺序扫描是不可能的,但关闭此变量会阻止计划程序在有其他可用方法时使用顺序扫描。默认值为 on

enable_sort (boolean) #

启用或禁用查询计划程序使用显式排序步骤。完全禁止显式排序是不可能的,但关闭此变量会阻止计划程序在有其他可用方法时使用显式排序。默认值为 on

enable_tidscan (boolean) #

启用或禁用查询计划程序使用 TID 扫描计划类型。默认值为 on

20.7.2. 计划程序成本常量 #

本节中描述的 cost 变量在任意尺度上进行测量。只有它们的相对值才有意义,因此将它们全部按相同因子向上或向下缩放不会改变计划程序的选择。默认情况下,这些成本变量基于顺序页面获取的成本;也就是说,seq_page_cost 通常设置为 1.0,其他成本变量则以此为参考进行设置。但如果您愿意,可以使用不同的尺度,例如特定计算机上的实际执行时间(以毫秒为单位)。

注意

遗憾的是,没有明确定义的方法来确定成本变量的理想值。最好将它们视为特定安装将接收的整个查询组合的平均值。这意味着仅根据几个实验就更改它们是非常冒险的。

seq_page_cost (浮点数) #

设置规划器对一系列顺序获取的一部分磁盘页面获取成本的估计值。默认值为 1.0。可以通过设置同名表空间参数来覆盖特定表空间中表和索引的此值(请参阅 ALTER TABLESPACE)。

random_page_cost (浮点数) #

设置规划器对非顺序获取的磁盘页面的成本的估计值。默认值为 4.0。可以通过设置同名表空间参数来覆盖特定表空间中表和索引的此值(请参阅 ALTER TABLESPACE)。

相对于 seq_page_cost 降低此值将导致系统更倾向于索引扫描;提高此值将使索引扫描看起来相对更昂贵。您可以同时提高或降低这两个值,以更改磁盘 I/O 成本相对于 CPU 成本(由以下参数描述)的重要性。

机械磁盘存储的随机访问通常比顺序访问贵四倍。但是,使用较低的默认值 (4.0),因为大多数对磁盘的随机访问(例如索引读取)都被认为在缓存中。默认值可以被认为是对随机访问建模为比顺序访问慢 40 倍,同时预期 90% 的随机读取被缓存。

如果您认为 90% 的缓存命中率对您的工作负载来说是一个不正确的假设,则可以增加 random_page_cost 以更好地反映随机存储读取的真实成本。相应地,如果您的数据很可能完全在缓存中,例如当数据库小于服务器总内存时,则可以适当降低 random_page_cost。与顺序存储相比,随机读取成本较低的存储(例如固态硬盘)也可能使用较低的 random_page_cost 值(例如 1.1)进行更好的建模。

提示

尽管系统允许你将 random_page_cost 设置为小于 seq_page_cost,但实际这样做没有意义。但是,如果数据库完全缓存在 RAM 中,则将它们设置为相等是有意义的,因为在这种情况下,按非顺序方式访问页面不会受到惩罚。此外,在高度缓存的数据库中,你应该相对于 CPU 参数降低这两个值,因为获取已在 RAM 中的页面的成本远小于正常情况下的成本。

cpu_tuple_cost (浮点数) #

设置规划器对查询期间处理每行成本的估计值。默认值为 0.01。

cpu_index_tuple_cost (浮点数) #

设置规划器对在索引扫描期间处理每个索引项的成本的估计值。默认值为 0.005。

cpu_operator_cost (浮点数) #

设置规划器对在查询期间执行的每个运算符或函数的处理成本的估计值。默认值为 0.0025。

parallel_setup_cost (浮点数) #

设置规划器对启动并行工作进程的成本的估计值。默认值为 1000。

parallel_tuple_cost (浮点数) #

设置规划器对将一个元组从一个并行工作进程传输到另一个进程的成本的估计值。默认值为 0.1。

min_parallel_table_scan_size (整数) #

设置并行扫描被考虑时必须扫描的最小表数据量。对于并行顺序扫描,扫描的表数据量始终等于表的大小,但当使用索引时,扫描的表数据量通常会更少。如果未指定单位,则将其视为块,即 BLCKSZ 字节,通常为 8kB。默认值为 8 兆字节 (8MB)。

min_parallel_index_scan_size (integer) #

设置并行扫描被考虑时必须扫描的最小索引数据量。请注意,并行索引扫描通常不会触及整个索引;规划器认为扫描实际会触及的页数才是相关的。此参数还用于决定特定索引是否可以参与并行 vacuum。请参见 VACUUM。如果未指定单位,则将其视为块,即 BLCKSZ 字节,通常为 8kB。默认值为 512 千字节 (512kB)。

effective_cache_size (integer) #

设置规划器对单个查询可用的磁盘缓存有效大小的假设。这会影响使用索引的成本估算;值越大,越有可能使用索引扫描;值越小,越有可能使用顺序扫描。设置此参数时,应同时考虑 PostgreSQL 的共享缓冲区和内核磁盘缓存中用于 PostgreSQL 数据文件的部分,尽管某些数据可能同时存在于这两个位置。此外,还要考虑不同表上并发查询的预期数量,因为它们必须共享可用空间。此参数不会影响 PostgreSQL 分配的共享内存大小,也不会保留内核磁盘缓存;它仅用于估算目的。系统也不会假设数据在查询之间保留在磁盘缓存中。如果未指定此值单位,则将其视为块,即 BLCKSZ 字节,通常为 8kB。默认值为 4 千兆字节 (4GB)。(如果 BLCKSZ 不为 8kB,则默认值会按比例缩放。)

jit_above_cost (浮点数) #

设置 JIT 编译激活的查询成本,如果已启用(请参阅 第 32 章)。执行 JIT 会消耗规划时间,但可以加速查询执行。将其设置为 -1 会禁用 JIT 编译。默认值为 100000

jit_inline_above_cost (浮点数) #

设置 JIT 编译尝试内联函数和运算符的查询成本。内联会增加规划时间,但可以提高执行速度。将其设置为小于 jit_above_cost 是没有意义的。将其设置为 -1 会禁用内联。默认值为 500000

jit_optimize_above_cost (浮点数) #

设置 JIT 编译应用昂贵优化操作的查询成本。此类优化会增加规划时间,但可以提高执行速度。将其设置为小于 jit_above_cost 是没有意义的,并且将其设置为大于 jit_inline_above_cost 也不太可能带来好处。将其设置为 -1 会禁用昂贵的优化操作。默认值为 500000

20.7.3. 遗传查询优化器 #

遗传查询优化器 (GEQO) 是一种使用启发式搜索进行查询规划的算法。这减少了复杂查询(那些连接许多关系的查询)的规划时间,代价是产生的计划有时不如正常穷举搜索算法找到的计划。有关更多信息,请参见 第 62 章

geqo (布尔值) #

启用或禁用遗传查询优化。默认情况下,此项已启用。通常最好不要在生产中将其关闭;geqo_threshold 变量提供了对 GEQO 的更精细控制。

geqo_threshold (整数) #

使用遗传查询优化来规划至少涉及这么多个 FROM 项的查询。(请注意,FULL OUTER JOIN 构造仅算作一个 FROM 项。)默认值为 12。对于较简单的查询,通常最好使用常规的穷举搜索规划器,但对于包含许多表的查询,穷举搜索会花费太长时间,通常比执行次优计划的惩罚时间更长。因此,查询大小的阈值是管理 GEQO 使用情况的便捷方法。

geqo_effort (整数) #

控制 GEQO 中规划时间与查询计划质量之间的权衡。此变量必须是 1 到 10 范围内的整数。默认值为 5。较大的值会增加用于查询规划的时间,但也增加了选择高效查询计划的可能性。

geqo_effort 实际上并不直接执行任何操作;它仅用于计算影响 GEQO 行为的其他变量的默认值(如下所述)。如果您愿意,可以手动设置其他参数。

geqo_pool_size (整数) #

控制 GEQO 使用的池大小,即遗传种群中的个体数量。它必须至少为 2,而通常有用的值为 100 至 1000。如果将其设置为 0(默认设置),则会根据 geqo_effort 和查询中的表数量选择合适的值。

geqo_generations (整数) #

控制 GEQO 使用的世代数,即算法的迭代次数。它必须至少为 1,而有用的值与池大小范围相同。如果将其设置为 0(默认设置),则会根据 geqo_pool_size 选择合适的值。

geqo_selection_bias (浮点数) #

控制 GEQO 使用的选择偏差。选择偏差是种群内的选择压力。值可以从 1.50 到 2.00;后者为默认值。

geqo_seed (浮点数) #

控制 GEQO 用于通过联接顺序搜索空间选择随机路径的随机数生成器的初始值。该值范围可以从 0(默认值)到 1。改变该值会改变所探索的联接路径集合,并可能找到更好或更差的最佳路径。

20.7.4. 其他计划程序选项 #

default_statistics_target (整数) #

为没有通过 ALTER TABLE SET STATISTICS 设置特定列目标的表列设置默认统计目标。较大的值会增加执行 ANALYZE 所需的时间,但可能会提高规划器估计的质量。默认值为 100。有关 PostgreSQL 查询规划器如何使用统计信息的详细信息,请参阅 第 14.2 节

constraint_exclusion (enum) #

控制查询规划器如何使用表约束来优化查询。允许的 constraint_exclusion 值为 on(检查所有表的约束)、off(从不检查约束)和 partition(仅检查继承子表和 UNION ALL 子查询的约束)。partition 是默认设置。它通常与传统的继承树一起使用以提高性能。

当此参数允许它用于特定表时,规划器会将查询条件与表的 CHECK 约束进行比较,并省略扫描条件与约束相矛盾的表。例如

CREATE TABLE parent(key integer, ...);
CREATE TABLE child1000(check (key between 1000 and 1999)) INHERITS(parent);
CREATE TABLE child2000(check (key between 2000 and 2999)) INHERITS(parent);
...
SELECT * FROM parent WHERE key = 2400;

启用约束排除后,此 SELECT 根本不会扫描 child1000,从而提高了性能。

目前,仅在通常用于通过继承树实现表分区的情况下,才会默认启用约束排除。为所有表启用它会产生额外的规划开销,这在简单查询中非常明显,并且通常对简单查询没有任何好处。如果您没有使用传统继承进行分区的表,您可能更愿意完全关闭它。(请注意,分区表的等效功能由单独的参数 enable_partition_pruning 控制。)

有关使用约束排除来实现分区的详细信息,请参阅 第 5.11.5 节

cursor_tuple_fraction (浮点) #

设置规划器对游标将检索的行分数的估计。默认值为 0.1。此设置的较小值使规划器偏向于对游标使用 快速启动 计划,这将快速检索前几行,同时可能需要很长时间才能获取所有行。较大的值更强调总估计时间。在最大设置 1.0 时,游标的规划与常规查询完全相同,仅考虑总估计时间,而不考虑第一行可能多快传递。

from_collapse_limit (整数) #

如果结果 FROM 列表的项目不超过此数量,规划器将子查询合并到上层查询中。较小的值会减少规划时间,但可能会产生较差的查询计划。默认值为八。有关详细信息,请参阅 第 14.3 节

将此值设置为 geqo_threshold 或更高值可能会触发使用 GEQO 规划器,导致非最佳计划。请参阅 第 20.7.3 节

jit (boolean) #

确定是否可以使用 PostgreSQLJIT 编译(如果可用,请参阅 第 32 章)。默认值为 on

join_collapse_limit (integer) #

如果不会导致超过此数量的项目列表,规划器会将显式 JOIN 构造(FULL JOIN 除外)重写为 FROM 项目列表。较小的值会减少规划时间,但可能会产生较差的查询计划。

默认情况下,此变量的设置与 from_collapse_limit 相同,这适用于大多数用途。将其设置为 1 会阻止对显式 JOIN 进行任何重新排序。因此,查询中指定的显式连接顺序将是连接关系的实际顺序。由于查询规划器并不总是选择最佳连接顺序,高级用户可以选择将此变量暂时设置为 1,然后显式指定所需的连接顺序。有关更多信息,请参阅 第 14.3 节

将此值设置为 geqo_threshold 或更高值可能会触发使用 GEQO 规划器,导致非最佳计划。请参阅 第 20.7.3 节

plan_cache_mode (enum) #

已准备好的语句(显式准备或隐式生成,例如通过 PL/pgSQL)可以使用自定义或通用计划执行。自定义计划针对每次执行使用其特定的一组参数值重新制作,而通用计划不依赖于参数值,可以在执行之间重复使用。因此,使用通用计划可以节省规划时间,但如果理想的计划在很大程度上取决于参数值,则通用计划可能效率低下。通常会自动进行这些选项之间的选择,但可以使用 plan_cache_mode 覆盖该选择。允许的值为 auto(默认值)、force_custom_planforce_generic_plan。在执行缓存计划时会考虑此设置,而不是在准备计划时考虑。有关更多信息,请参阅 PREPARE

recursive_worktable_factor (floating point) #

将计划程序对 递归查询 的工作表平均大小的估计值设置为查询的初始非递归项的估计大小的倍数。这有助于计划程序选择最合适的方法来将工作表与查询的其他表连接起来。默认值为 10.0。当递归从一个步骤到下一个步骤的 扇出 较低时,可以使用 1.0 等较小的值,例如在最短路径查询中。图形分析查询可能受益于大于默认值的值。