这些配置参数提供了一种粗略的方法来影响查询优化器选择的查询计划。如果优化器为特定查询选择的默认计划不是最优的,一个临时的解决方案是使用这些配置参数之一强制优化器选择不同的计划。改进优化器选择的计划质量的更好方法包括调整规划器成本常数(参见第 19.7.2 节),手动运行ANALYZE
,增加default_statistics_target配置参数的值,并使用ALTER TABLE SET STATISTICS
增加为特定列收集的统计信息量。
enable_async_append
(boolean
) #启用或禁用查询规划器使用异步感知附加计划类型。默认值为on
。
enable_bitmapscan
(boolean
) #启用或禁用查询规划器使用位图扫描计划类型。默认值为on
。
enable_gathermerge
(boolean
) #启用或禁用查询规划器使用收集合并计划类型。默认值为on
。
enable_group_by_reordering
(boolean
) #控制查询规划器是否生成一个计划,该计划将提供按照计划的子节点的键的顺序(例如索引扫描)排序的GROUP BY
键。禁用时,查询规划器将生成一个计划,其中GROUP BY
键仅排序以匹配ORDER BY
子句(如果有)。启用后,规划器将尝试生成更有效的计划。默认值为on
。
enable_hashagg
(boolean
) #启用或禁用查询规划器使用哈希聚合计划类型。默认值为on
。
enable_hashjoin
(boolean
) #启用或禁用查询规划器使用哈希连接计划类型。默认值为on
。
enable_incremental_sort
(boolean
) #启用或禁用查询规划器使用增量排序步骤。默认值为on
。
enable_indexscan
(boolean
) #启用或禁用查询规划器使用索引扫描和仅索引扫描计划类型。默认值为on
。另请参见enable_indexonlyscan。
enable_indexonlyscan
(boolean
) #启用或禁用查询规划器使用仅索引扫描计划类型(参见第 11.9 节)。默认值为on
。还必须启用enable_indexscan设置,查询规划器才会考虑仅索引扫描。
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
) #启用或禁用查询规划器从查询计划中删除分区表的分区的功能。这还控制规划器生成查询计划的能力,该查询计划允许查询执行器在查询执行期间删除(忽略)分区。默认值为on
。有关详细信息,请参见第 5.12.4 节。
enable_partitionwise_join
(boolean
) #启用或禁用查询规划器使用分区连接,这允许通过连接匹配的分区来执行分区表之间的连接。分区连接目前仅在连接条件包括所有分区键(必须具有相同的数据类型并且具有一对一匹配的子分区集)时适用。启用此设置后,最终计划中内存使用受work_mem
限制的节点数量可能会根据扫描的分区数量线性增加。这会导致查询执行期间整体内存消耗大幅增加。查询规划在内存和 CPU 方面也变得更加昂贵。默认值为off
。
enable_partitionwise_aggregate
(boolean
) #启用或禁用查询规划器对分区分组或聚合的使用。分区分组或聚合允许对分区表进行分组或聚合,以便为每个分区单独执行。如果 GROUP BY
子句不包含分区键,则只能在每个分区的基础上执行部分聚合,并且必须在稍后执行最终化。启用此设置后,最终计划中受 work_mem
限制内存使用的节点数量可能会根据扫描的分区数量线性增加。这可能导致查询执行期间整体内存消耗大幅增加。查询规划在内存和 CPU 方面也会变得显著更加昂贵。默认值为 off
。
enable_partitionwise_aggregate
(boolean
) #控制查询规划器是否生成一个计划,该计划将提供按照查询的 ORDER BY
/ DISTINCT
聚合函数所需顺序预先排序的行。禁用时,查询规划器将生成一个计划,该计划始终要求执行器在执行包含 ORDER BY
或 DISTINCT
子句的每个聚合函数的聚合之前执行排序。启用时,规划器将尝试生成一个更有效的计划,该计划为聚合函数提供按照它们进行聚合所需顺序预先排序的输入。默认值为 on
。
enable_presorted_aggregate
(boolean
) #启用或禁用查询规划器对顺序扫描计划类型的使用。完全禁止顺序扫描是不可能的,但如果存在其他可用方法,则关闭此变量会阻止规划器使用顺序扫描。默认值为 on
。
enable_seqscan
(boolean
) #启用或禁用查询规划器对显式排序步骤的使用。完全禁止显式排序是不可能的,但如果存在其他可用方法,则关闭此变量会阻止规划器使用显式排序。默认值为 on
。
enable_sort
(boolean
) #启用或禁用查询规划器对TID扫描计划类型的使用。默认值为 on
。
本节中描述的成本变量以任意尺度衡量。只有它们的相对值才重要,因此将它们全部按相同因子放大或缩小不会导致规划器的选择发生任何变化。默认情况下,这些成本变量基于顺序页面获取的成本;也就是说,seq_page_cost
通常设置为 1.0
,而其他成本变量则参考该值进行设置。但是,如果您愿意,可以使用不同的尺度,例如特定机器上的实际执行时间(以毫秒为单位)。
不幸的是,没有明确的方法来确定成本变量的理想值。最好将它们视为特定安装将接收的整个查询组合的平均值。这意味着仅根据少数实验来更改它们是非常冒险的。
seq_page_cost
(floating point
) #设置规划器对作为一系列顺序获取的一部分的磁盘页面获取的成本的估计值。默认值为 1.0。可以通过设置具有相同名称的表空间参数来覆盖特定表空间中的表和索引的此值(请参阅ALTER TABLESPACE)。
random_page_cost
(floating point
) #设置规划器对非顺序获取的磁盘页面的成本的估计值。默认值为 4.0。可以通过设置具有相同名称的表空间参数来覆盖特定表空间中的表和索引的此值(请参阅ALTER TABLESPACE)。
相对于 seq_page_cost
降低此值将导致系统更喜欢索引扫描;提高此值将使索引扫描看起来相对更昂贵。您可以一起提高或降低这两个值,以更改磁盘 I/O 成本相对于 CPU 成本的重要性,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
(floating point
) #设置规划器对查询期间处理每一行的成本的估计值。默认值为 0.01。
cpu_index_tuple_cost
(floating point
) #设置规划器对索引扫描期间处理每个索引条目的成本的估计值。默认值为 0.005。
cpu_operator_cost
(floating point
) #设置规划器对查询期间执行的每个运算符或函数的成本的估计值。默认值为 0.0025。
parallel_setup_cost
(floating point
) #设置规划器对启动并行工作进程的成本的估计值。默认值为 1000。
parallel_tuple_cost
(floating point
) #设置规划器对将一个元组从一个并行工作进程传输到另一个进程的成本的估计值。默认值为 0.1。
min_parallel_table_scan_size
(integer
) #设置为了考虑并行扫描而必须扫描的最小表数据量。对于并行顺序扫描,扫描的表数据量始终等于表的大小,但是当使用索引时,扫描的表数据量通常会较少。如果此值在没有单位的情况下指定,则将其视为块,即 BLCKSZ
字节,通常为 8kB。默认值为 8 兆字节(8MB
)。
min_parallel_index_scan_size
(integer
) #设置为了考虑并行扫描而必须扫描的最小索引数据量。请注意,并行索引扫描通常不会触及整个索引;相关的是规划器认为扫描实际会触及的页数。此参数还用于决定特定索引是否可以参与并行清理。请参阅VACUUM。如果此值在没有单位的情况下指定,则将其视为块,即 BLCKSZ
字节,通常为 8kB。默认值为 512 千字节(512kB
)。
effective_cache_size
(integer
) #设置规划器对单个查询可用的磁盘缓存有效大小的假设。这会影响索引使用成本的估算;较高的值会使索引扫描更有可能被使用,较低的值会使顺序扫描更有可能被使用。在设置此参数时,您应该同时考虑 PostgreSQL 的共享缓冲区和内核磁盘缓存中用于 PostgreSQL 数据文件的部分,尽管某些数据可能同时存在于这两个地方。此外,还要考虑不同表上并发查询的预期数量,因为它们将需要共享可用空间。此参数对 PostgreSQL 分配的共享内存大小没有影响,也不会保留内核磁盘缓存;它仅用于估算目的。系统也不假设数据在查询之间保留在磁盘缓存中。如果此值在指定时没有单位,则将其视为块,即 BLCKSZ
字节,通常为 8kB。默认值为 4 千兆字节 (4GB
)。(如果 BLCKSZ
不是 8kB,则默认值会按比例缩放。)
jit_above_cost
(浮点数
) #设置查询成本的阈值,当查询成本高于此值时,如果启用了 JIT 编译,则会激活 JIT 编译(请参阅 第 30 章)。执行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
。
遗传查询优化器 (GEQO) 是一种使用启发式搜索进行查询规划的算法。这减少了复杂查询(连接多个关系)的规划时间,但代价是生成的计划有时不如常规穷举搜索算法找到的计划。有关更多信息,请参阅 第 60 章。
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。如果将其设置为零(默认设置),则会根据 geqo_effort
和查询中的表数选择合适的值。
geqo_generations
(整数
) #控制 GEQO 使用的代数,即算法的迭代次数。它必须至少为 1,有用的值与池大小在同一范围内。如果将其设置为零(默认设置),则会根据 geqo_pool_size
选择合适的值。
geqo_selection_bias
(浮点数
) #控制 GEQO 使用的选择偏差。选择偏差是群体内的选择压力。值可以从 1.50 到 2.00;后者是默认值。
geqo_seed
(浮点数
) #控制 GEQO 使用的随机数生成器的初始值,以在连接顺序搜索空间中选择随机路径。该值的范围可以从零(默认值)到一。更改该值会更改探索的连接路径集,并可能会导致找到更好或更差的最佳路径。
default_statistics_target
(整数
) #设置表列的默认统计信息目标,这些表列没有通过 ALTER TABLE SET STATISTICS
设置列特定目标。较大的值会增加进行 ANALYZE
所需的时间,但可能会提高规划器估计的质量。默认值为 100。有关 PostgreSQL 查询规划器使用统计信息的更多信息,请参阅 第 14.2 节。
constraint_exclusion
(枚举
) #控制查询规划器使用表约束来优化查询。 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.12.5 节。
cursor_tuple_fraction
(浮点数
) #设置规划器对游标检索的行数的估计比例。默认值为 0.1。此设置的值越小,规划器越倾向于对游标使用“快速启动”计划,该计划会快速检索前几行,但可能需要较长时间才能获取所有行。值越大,则越强调估计的总时间。在最大设置值 1.0 时,游标的规划方式与常规查询完全相同,仅考虑估计的总时间,而不考虑何时可以交付第一行。
from_collapse_limit
(integer
) #如果生成的 FROM
列表中的项不超过此数量,则规划器会将子查询合并到上层查询中。值越小,规划时间越短,但可能会产生较差的查询计划。默认值为 8。有关更多信息,请参阅第 14.3 节。
将此值设置为 geqo_threshold 或更高可能会触发使用 GEQO 规划器,从而导致非最佳计划。请参阅第 19.7.3 节。
jit
(boolean
) #确定是否JIT如果可用,PostgreSQL可以使用编译(请参阅第 30 章)。默认值为 on
。
join_collapse_limit
(integer
) #当生成的列表中的项不超过此数量时,规划器会将显式 JOIN
构造(FULL JOIN
除外)重写为 FROM
项的列表。值越小,规划时间越短,但可能会产生较差的查询计划。
默认情况下,此变量的设置与 from_collapse_limit
相同,这适用于大多数情况。将其设置为 1 会阻止对显式 JOIN
进行任何重新排序。因此,查询中指定的显式连接顺序将是关系连接的实际顺序。由于查询规划器并不总是选择最佳连接顺序,因此高级用户可以选择暂时将此变量设置为 1,然后显式指定所需的连接顺序。有关更多信息,请参阅第 14.3 节。
将此值设置为 geqo_threshold 或更高可能会触发使用 GEQO 规划器,从而导致非最佳计划。请参阅第 19.7.3 节。
plan_cache_mode
(enum
) #预处理语句(显式预处理或隐式生成,例如通过 PL/pgSQL 生成)可以使用自定义计划或通用计划执行。自定义计划是使用其特定的参数值针对每次执行重新创建的,而通用计划不依赖于参数值,可以在多次执行中重复使用。因此,使用通用计划可以节省规划时间,但如果理想计划强烈依赖于参数值,则通用计划可能效率低下。通常会自动在这两个选项之间做出选择,但可以使用 plan_cache_mode
覆盖此选择。允许的值为 auto
(默认值)、force_custom_plan
和 force_generic_plan
。在要执行缓存计划时,而不是在准备计划时,会考虑此设置。有关更多信息,请参阅PREPARE。
recursive_worktable_factor
(floating point
) #设置规划器对递归查询的工作表的平均大小的估计,作为查询初始非递归项的估计大小的倍数。这有助于规划器选择将工作表连接到查询的其他表的最合适方法。默认值为 10.0
。当递归从一个步骤到下一步的 “扇出” 较低时(例如在最短路径查询中),较小的值(如 1.0
)会很有帮助。图分析查询可能会受益于大于默认值的值。
如果您在文档中发现任何不正确、与您使用特定功能的经验不符或需要进一步澄清的内容,请使用此表格报告文档问题。