在 PostgreSQL 中强制执行连接顺序#postgresql认证

news/2024/7/7 20:35:59 标签: postgresql, 数据库

让我们首先创建一些表:

PgSQL
plan=# SELECT   'CREATE TABLE x' || id || ' (id int)' 
 FROM 	   generate_series(1, 5) AS id;
         ?column?         
--------------------------
 CREATE TABLE x1 (id int)
 CREATE TABLE x2 (id int)
 CREATE TABLE x3 (id int)
 CREATE TABLE x4 (id int)
 CREATE TABLE x5 (id int)
(5 rows)

在 PostgreSQL 中,我们可以轻松地使用 SQL 创建 SQL。psql 的优点在于,只需运行 gexec 即可将先前的输出用作新输入:

plan=# gexec
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE

瞧,我们有 5 个表可以作为示例数据结构。

在 POSTGRESQL 中连接表

#PG培训#PG考试#postgresql培训#postgresql考试
以下查询显示了使用我们刚刚创建的表的简单连接:

PgSQL
plan=# explain (timing, analyze)  SELECT *
           FROM    x1 JOIN x2 ON  (x1.id = x2.id)
                      JOIN x3 ON  (x2.id = x3.id)
                      JOIN x4 ON  (x3.id = x4.id)
                      JOIN x5 ON  (x4.id = x5.id);
…
Planning Time: 0.069 ms
Execution Time: 0.046 ms

这里的重要观察是什么?让我们来看看规划时间。PostgreSQL 需要 0.297 毫秒来找到运行查询的最佳执行计划(= 执行策略)。出现的问题是:规划器在哪里需要时间来规划查询?问题是:即使使用如上所示的显式连接,PostgreSQL 也会隐式连接这些表并决定最佳连接顺序。这在现实生活中意味着什么?让我们考虑一个连接“a join b join c”:即使我们编写一个 SQL 说连接“a to b”,优化器仍可能决定投票支持“c join a join b”,以防它保证相同的结果。为什么这如此重要?因为它提供了很大的效率。让优化器决定最佳连接顺序是一项重要的内部优化。

然而,我们必须牢记规划时间——尤其是如果涉及很多桌子(10 张以上?)。

控制 SQL 中的连接行为

如果规划时间是一个问题,我们可以强制 PostgreSQL 使用我们希望它使用的连接顺序。控制此行为的变量是 join_collapse_limit。这是什么意思?基本上它控制隐式规划的显式连接的数量。换句话说:PostgreSQL 可以优化多少个显式连接。

如果我们将这个变量设置为 1,则意味着我们强制 PostgreSQL 使用我们选择的连接顺序:


plan=# SET join_collapse_limit TO 1;
SET
plan=# explain (timing, analyze)  SELECT *
           FROM    x1 JOIN x2 ON  (x1.id = x2.id)
                      JOIN x3 ON  (x2.id = x3.id)
                      JOIN x4 ON  (x3.id = x4.id)
                      JOIN x5 ON  (x4.id = x5.id);
…
Planning Time: 0.069 ms
Execution Time: 0.046 ms

真正值得注意的是规划速度的显著提升。我们可以看到惊人的 4 倍加速。

但是,我还要提醒大家:优化器首先尝试重新构建连接是有原因的。如果查询比我们在此示例中看到的更昂贵,那么投入更多时间创建计划就很有意义了。换句话说:除非最终用户完全了解正在发生的事情,否则更改此变量可能会适得其反。因此,我们建议在更改此设置之前使用真实数据和真实工作负载测试您的查询和整个设置。通常,只更改单个查询的变量并保留 postgresql.conf 中的默认值(与所有其他操作一样)也是有益的。
在这里插入图片描述


http://www.niftyadmin.cn/n/5535059.html

相关文章

第二十条:与抽象类相比,优先选择接口

要定义多种实现的类型:JAVA有两种机制:接口和抽象类。这两种机制都支持为某些实例方法提供实现,但二者有个重要的区别:要实现由抽象类定义的类型,这个类必须是抽象类的子类。因为Java只允许单继承,对抽象类…

​香橙派AIpro测评:usb鱼眼摄像头的Camera图像获取

一、前言 近期收到了一块受到业界人士关注的开发板"香橙派AIpro",因为这块板子具有极高的性价比,同时还可以兼容ubuntu、安卓等多种操作系统,今天博主便要在一块832g的香橙派AI香橙派AIpro进行YoloV5s算法的部署并使用一个外接的鱼眼USB摄像头…

Frrouting快速入门——OSPF组网(一)

FRR简介 FRR是FRRouting的简称,是一个开源的路由交换软件套件。其作者源自老牌项目quaga的成员,也可以算是quaga的新版本。 使用时一般查看此文档:https://docs.frrouting.org/projects/dev-guide/en/latest/index.html FRR支持的协议众多…

HarmonyOS APP应用开发项目- MCA助手(Day02持续更新中~)

简言: gitee地址:https://gitee.com/whltaoin_admin/money-controller-app.git端云一体化开发在线文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/agc-harmonyos-clouddev-view-0000001700053733-V5注:…

系统安全体系架构规划框架

安全技术体系架构是对组织机构信息技术系统的安全体系结构的整体描述。安全技术体系架构框架是拥有信息技术系统的组织机构根据其策略的要求和风险评估的结果,参考相关技术体系构架的标准和最佳实践,结合组织机构信息技术系统的具体现状和需求&#xff0…

java通过jts获取点在线段中的位置

在Java中,可以使用JTS(Java Topology Suite)库来获取点在线段的垂足点位置。以下是一个简单的示例代码,展示了如何使用JTS获取点到线段的垂足点位置: 首先,确保你的项目中包含了JTS库。 import org.locati…

Python学习之小游戏--坦克大作战

今天跟视频学习了Python实现坦克大作战小游戏,挺有意思的,一起来玩吧~ 按空格发射子弹,上下左右键实现移动,ESC键无限复活。 import pygame,time,random from pygame.sprite import Sprite SCREEN_WIDTH800 SCREEN_HEIGHT500 BG…

C++(第四天----拷贝函数、类的组合、类的继承)

一、拷贝构造函数(复制构造函数) 1、概念 拷贝构造函数,它只有一个参数,参数类型是本类的引用。如果类的设计者不写拷贝构造函数,编译器就会自动生成拷贝构造函数。大多数情况下,其作用是实现从源对象到目…