19.7. 查询计划

19 .7.1. 规划器方法配置

这些配置参数提供了一种影响查询优化器选择的查询计划的粗略方法。如果优化器为特定查询选择的默认计划不是最佳选择,那么临时解决方案是使用这些配置参数之一来强制优化器选择其他计划。改善优化程序选择的计划质量的更好方法包括调整计划程序成本常量(请参见Section 19.7.2),手动运行ANALYZE,增加default_statistics_target配置参数的值以及使用ALTER TABLE SET STATISTICS增加针对特定列收集的统计信息量。

19 .7.2. 计划者成本常数

本节中描述的* cost *变量以任意比例进行度量。只有它们的相对值很重要,因此将它们全部按相同的系数上下缩放将不会导致计划者的选择发生变化。默认情况下,这些成本变量基于 Sequences 页面获取的成本;也就是说,通常将seq_page_cost设置为1.0,其他成本变量则以此为基准进行设置。但是您可以根据需要使用不同的比例,例如特定机器上的实际执行时间(以毫秒为单位)。

Note

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

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

对机械磁盘存储的随机访问通常比 Sequences 访问的四倍昂贵。但是,使用较低的默认值(4.0),因为假定对磁盘的大多数随机访问(如索引读取)位于缓存中。可以将默认值认为是对随机访问进行建模的速度比 Sequences 慢 40 倍,同时预计 90%的随机读取将被缓存。

如果您认为 90%的缓存速率是对工作负载的错误假设,则可以增加 random_page_cost 以更好地反映随机存储读取的真实成本。相应地,如果您的数据有可能完全位于缓存中(例如,当数据库小于服务器总内存时),则减少 random_page_cost 可能是适当的。相对于 Sequences 存储的随机读取成本较低的存储,例如固态驱动器,也可以通过对 random_page_cost 较低的值进行更好的建模。

Tip

尽管系统允许您将random_page_cost设置为小于seq_page_cost,但是这样做并不实际。但是,如果将数据库完全缓存在 RAM 中,则将它们设置为相等是有意义的,因为在这种情况下,按 Sequences 触摸页面不会造成任何损失。同样,在高速缓存的数据库中,您应该降低两个值,相对于 CPU 参数,这是因为获取 RAM 中已经存在的页面的成本比通常要小得多。

19 .7.3. 遗传查询优化器

遗传查询优化器(GEQO)是一种使用启发式搜索进行查询计划的算法。这样可以减少复杂查询(那些包含许多关系的查询)的计划时间,但所产生的计划有时会比通常的穷举搜索算法所发现的计划差。有关更多信息,请参见Chapter 60

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

19 .7.4. 其他计划者选项

当此参数允许它用于特定表时,计划者将查询条件与表的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控制。)

有关使用约束排除来实现分区的更多信息,请参考Section 5.10.5

将此值设置为geqo_threshold或更大可能会触发使用 GEQO 计划程序,从而导致计划不理想。参见Section 19.7.3

默认情况下,此变量的设置与from_collapse_limit相同,适用于大多数用途。将其设置为 1 可防止对显式JOIN进行任何重新排序。因此,查询中指定的显式连接 Sequences 将是关系之间的实际连接 Sequences。由于查询计划者并不总是选择最佳的连接 Sequences,因此高级用户可以选择将该变量临时设置为 1,然后明确指定他们想要的连接 Sequences。有关更多信息,请参见Section 14.3

将此值设置为geqo_threshold或更大可能会触发使用 GEQO 计划程序,从而导致计划不理想。参见Section 19.7.3

更具体地说,将此值设置为on会将Gather节点添加到看起来安全的任何查询计划的顶部,以便查询在并行工作程序内部运行。即使当并行工作器不可用或无法使用时,除非计划者认为这将导致查询失败,否则将禁止诸如在并行查询上下文中禁止启动子事务之类的操作。如果设置此选项时发生故障或意外结果,则查询中使用的某些功能可能需要标记为PARALLEL UNSAFE(或者可能是PARALLEL RESTRICTED)。

将此值设置为regress具有与将其设置为on相同的所有效果,以及一些旨在促进自动回归测试的其他效果。通常,来自并行工作程序的消息包括上下文行,指示该行,但是设置regress会禁止该行,因此输出与非并行执行中的输出相同。同样,通过此设置添加到计划中的Gather节点隐藏在EXPLAIN输出中,以便输出与如果将此设置设为off所获得的结果匹配。

上一章 首页 下一章