↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1
历史版本PostgreSQL 8.2 已于 2011 年 12 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

17.6. 查询规划 #

17.6.1. 规划器方法配置 #

这些配置参数提供了一种较为粗糙的方法,用于影响查询优化器所选择的查询计划。 如果优化器为某个特定查询选择的默认计划并不理想,一种临时解决方案是 使用这些配置参数强制优化器选择另一种计划。不过,永久关闭其中 某项设置很少是个好主意。改善优化器所选计划质量的更好办法包括 调整规划器代价常数 (见规划器代价常量)、手工运行 ANALYZE、增加 default_statistics_target 配置参数的值,以及使用 ALTER TABLE SET STATISTICS 增加为特定列收集的统计信息量。

enable_bitmapscan (boolean) #

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

enable_hashagg (boolean) #

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

enable_hashjoin (boolean) #

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

enable_indexscan (boolean) #

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

enable_mergejoin (boolean) #

启用或禁用查询规划器对归并连接计划类型的使用。默认值为 on。

enable_nestloop (boolean) #

允许或禁止查询规划器使用嵌套循环连接计划。它不可能完全禁止嵌套循环连接,但是关闭这个变量将使得规划器尽可能优先使用其他方法。默认值是on。

enable_seqscan (boolean) #

允许或禁止查询规划器使用顺序扫描计划类型。它不可能完全禁止顺序扫描,但是关闭这个变量将使得规划器尽可能优先使用其他方法。默认值是on。

enable_sort (boolean) #

允许或禁止查询规划器使用显式排序步骤。它不可能完全禁止显式排序,但是关闭这个变量将使得规划器尽可能优先使用其他方法。默认值是on。

enable_tidscan (boolean) #

允许或禁止查询规划器使用TID扫描计划类型。默认值是on。

17.6.2. 规划器代价常量 #

这一节中描述的代价变量可以按照任意尺度衡量。我们只关心它们的相对值,将它们以相同的因子缩放不会影响规划器的选择。默认情况下,这些代价变量是基于顺序页面获取的代价的,即seq_page_cost被设置为1.0并且其他代价变量都参考它来设置。不过你可以使用你喜欢的不同尺度,例如在一个特定机器上以毫秒为单位的实际执行时间。

注意

没有明确的方法可以确定代价变量的理想值。最好将它们视为某个数据库安装实例所接收的全部查询组合的平均值。因此,仅凭少数几次试验就修改它们是非常冒险的。

seq_page_cost (floating point) #

设置规划器对一系列顺序磁盘页面读取中单次读取的代价估计。默认值是 1.0。

random_page_cost (floating point) #

设置规划器对一次非顺序磁盘页面读取的代价估计。默认值是 4.0。 减少这个值(相对于 seq_page_cost)将导致系统 更倾向于索引扫描;提高它将让索引扫描看起来相对更昂贵。你可以 一起提高或降低两个值来改变磁盘 I/O 代价相对于 CPU 代价的重要性, 后者由下列参数描述。

提示

尽管系统允许将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。

effective_cache_size (integer) #

设置规划器对一个单一查询可用的有效磁盘缓存尺寸的假设。 这个参数会被考虑在使用一个索引的代价估计中,更高的数值会使得索引扫描更可能被使用,更低的数值会使得顺序扫描更可能被使用。 在设置这个参数时,你还应该考虑PostgreSQL的共享缓冲区以及将被用于PostgreSQL数据文件的内核磁盘缓存,尽管有些数据可能在两个地方都存在。 另外,还要考虑预计在不同表上的并发查询数目,因为它们必须共享可用的空间。 这个参数对PostgreSQL分配的共享内存尺寸没有影响,它也不会预留内核磁盘缓存,它只用于估计的目的。系统也不会假设在查询之间数据会保留在磁盘缓存中。 默认值是 128 兆字节(128MB)。

17.6.3. 遗传查询优化器 #

geqo (boolean) #

允许或禁止遗传查询优化,它是一种试图不做穷举搜索来进行查询规划的算法。默认是启用。geqo_threshold变量提供了一种更细粒度的方式,可以对某些类别的查询禁用 GEQO。

geqo_threshold (integer) #

只有当涉及的FROM项数量至少有这么多个的时候,才使用遗传查询优化(注意一个FULL OUTER JOIN只被计为一个FROM项)。默认值是 12。对于更简单的查询,通常会使用普通的穷举搜索规划器,但是对于有很多表的查询穷举搜索会花很长时间,通常比执行一个次优的计划带来的惩罚值还要长。因此,在查询尺寸上的一个阈值是管理 GEQO 使用的一种方便的方法。

geqo_effort (integer) #

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

geqo_effort实际并不直接做任何事情;它只是被用来计算其他影响 GEQO 行为的变量(如下所述)的默认值。如果你愿意,你可以手工设置其他参数。

geqo_pool_size (integer) #

控制 GEQO 使用的池尺寸,它就是遗传种群中的个体数目。它必须至少为 2,且有用的值通常在 100 到 1000 之间。如果它被设置为零(默认设置)则会基于geqo_effort和查询中表的数量选择一个合适的值。

geqo_generations (integer) #

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

geqo_selection_bias (floating point) #

控制 GEQO 使用的选择偏好。选择偏好是种群中的选择压力。值可以是 1.5 到 2.0 之间,后者是默认值。

17.6.4. 其他规划器选项 #

default_statistics_target (integer) #

为没有通过ALTER TABLE SET STATISTICS设置列相关目标的表列设置默认统计目标。更大的值增加了需要做ANALYZE的时间,但是可能会改善规划器的估计质量。默认值是 10。有关PostgreSQL查询规划器使用的统计信息的更多内容, 请参考第 13.2 节。

constraint_exclusion (boolean) #

允许或禁止查询规划器使用表约束来优化查询。默认值是off。

当这个参数为on时,规划器会比较查询条件与表的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,从而提高性能。

目前,constraint_exclusion默认是禁用的,因为如果查询计划被缓存,它有产生错误结果的风险——如果表约束被更改或删除,先前生成的计划现在可能已经不正确,而且没有内建的机制强制重新规划。(这个缺陷可能会在将来的PostgreSQL版本中解决。)保持禁用的另一个原因是约束检查的代价相对较高,而且在许多情况下不会带来任何节省。建议只在确实使用为利用该特性而设计的分区表时才启用它。

更多关于使用约束排除和分区的信息请参阅第 5.9 节。

from_collapse_limit (integer) #

如果生成的FROM列表不超过这么多项,规划器将把子查询融合到上层查询。较小的值可以减少规划时间,但是可能会生成较差的查询计划。默认值是 8。通常应让它小于geqo_threshold。更多信息见第 13.3 节。

join_collapse_limit (integer) #

如果得出的列表中不超过这么多项,那么规划器将把显式JOIN(除了FULL JOIN)结构重写到 FROM项列表中。较小的值可减少规划时间,但是可能会生成差些的查询计划。

默认情况下,这个变量被设置成和from_collapse_limit相同,这样适合大多数使用。把它设置为 1 可避免任何显式JOIN的重排序。因此查询中指定的显式连接顺序就是关系被连接的实际顺序。因为查询规划器并不是总能选取最优的连接顺序,高级用户可以选择暂时把这个变量设置为 1,然后显式地指定他们想要的连接顺序。更多信息请见第 13.3 节。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。