KingbaseES 数据库连接
一、数据准备:
create table student(
id int ,
s_name varchar(20),
t_id int
);
create table teacher(
id int ,
t_name varchar(20)
);
insert into student values (1,'zhangsan',3) , (2,'lisi',2) , (3,'wangwu',1), (4,'zhaoliu',4) ;
insert into teacher values(1, 'zhaolaoshi'),(2, 'qianlaoshi'),(3, 'sunlaoshi'),(6, 'lilaoshi');
以上为准备数据。
以下为测试准备SQL,不需要执行。
create index student_tid_idx on student(t_id);
create index student_id_idx on student(id);
create index teacher_id_idx on teacher(id);
reindex table student;
reindex table teacher;
set enable_seqscan to off;
set enable_hashjoin to off;
set enable_mergejoin to off;
drop index student_tid_idx;
drop index student_id_idx;
drop index teacher_id_idx;
二、数据库连接种类
1.自然连接
不需要指定连接列,也不需要使用on语句,默认按照相同列名进行筛选。
select * from student natural join teacher;
demo=# select * from student natural join teacher;
id | s_name | t_id | t_name
----+----------+------+------------
1 | zhangsan | 3 | zhaolaoshi
2 | lisi | 2 | qianlaoshi
3 | wangwu | 1 | sunlaoshi
(3 行记录)
2.内连接
(1)隐式语法
select * from student s,teacher t where s.t_id = t.id;
demo=# select * from student s,teacher t where s.t_id = t.id;
id | s_name | t_id | id | t_name
----+----------+------+----+------------
3 | wangwu | 1 | 1 | zhaolaoshi
2 | lisi | 2 | 2 | qianlaoshi
1 | zhangsan | 3 | 3 | sunlaoshi
(3 行记录)
(2)显示语法
写法1:
select * from student s inner join teacher t on s.t_id = t.id;
demo=# select * from student s inner join teacher t on s.t_id = t.id;
id | s_name | t_id | id | t_name
----+----------+------+----+------------
3 | wangwu | 1 | 1 | zhaolaoshi
2 | lisi | 2 | 2 | qianlaoshi
1 | zhangsan | 3 | 3 | sunlaoshi
(3 行记录)
写法2:
select * from student s join teacher t on s.t_id = t.id;
demo=# select * from student s join teacher t on s.t_id = t.id;
id | s_name | t_id | id | t_name
----+----------+------+----+------------
3 | wangwu | 1 | 1 | zhaolaoshi
2 | lisi | 2 | 2 | qianlaoshi
1 | zhangsan | 3 | 3 | sunlaoshi
(3 行记录)
3.外连接
(1)左外连接
写法1:
select * from student s left join teacher t on s.t_id = t.id;
demo=# select * from student s left join teacher t on s.t_id = t.id;
id | s_name | t_id | id | t_name
----+----------+------+----+------------
3 | wangwu | 1 | 1 | zhaolaoshi
2 | lisi | 2 | 2 | qianlaoshi
1 | zhangsan | 3 | 3 | sunlaoshi
4 | zhaoliu | 4 | |
(4 行记录)
写法2:
select * from student s left outer join teacher t on s.t_id = t.id;
demo=# select * from student s left outer join teacher t on s.t_id = t.id;
id | s_name | t_id | id | t_name
----+----------+------+----+------------
3 | wangwu | 1 | 1 | zhaolaoshi
2 | lisi | 2 | 2 | qianlaoshi
1 | zhangsan | 3 | 3 | sunlaoshi
4 | zhaoliu | 4 | |
(4 行记录)
写法3:
select * from student s,teacher t where s.t_id = t.id(+);
demo=# select * from student s,teacher t where s.t_id = t.id(+);
id | s_name | t_id | id | t_name
----+----------+------+----+------------
3 | wangwu | 1 | 1 | zhaolaoshi
2 | lisi | 2 | 2 | qianlaoshi
1 | zhangsan | 3 | 3 | sunlaoshi
4 | zhaoliu | 4 | |
(4 行记录)
(2)右外连接
写法1:
select * from student s right join teacher t on s.t_id = t.id;
demo=# select * from student s right join teacher t on s.t_id = t.id;
id | s_name | t_id | id | t_name
----+----------+------+----+------------
3 | wangwu | 1 | 1 | zhaolaoshi
2 | lisi | 2 | 2 | qianlaoshi
1 | zhangsan | 3 | 3 | sunlaoshi
| | | 6 | lilaoshi
(4 行记录)
写法2:
select * from student s right outer join teacher t on s.t_id = t.id;
demo=# select * from student s right outer join teacher t on s.t_id = t.id;
id | s_name | t_id | id | t_name
----+----------+------+----+------------
3 | wangwu | 1 | 1 | zhaolaoshi
2 | lisi | 2 | 2 | qianlaoshi
1 | zhangsan | 3 | 3 | sunlaoshi
| | | 6 | lilaoshi
(4 行记录)
写法3:
select * from student s,teacher t where s.t_id(+) = t.id;
demo=# select * from student s,teacher t where s.t_id(+) = t.id;
id | s_name | t_id | id | t_name
----+----------+------+----+------------
3 | wangwu | 1 | 1 | zhaolaoshi
2 | lisi | 2 | 2 | qianlaoshi
1 | zhangsan | 3 | 3 | sunlaoshi
| | | 6 | lilaoshi
(4 行记录)
(3)全外连接
写法1:
select * from student s full join teacher t on s.t_id = t.id;
demo=# select * from student s full join teacher t on s.t_id = t.id;
id | s_name | t_id | id | t_name
----+----------+------+----+------------
3 | wangwu | 1 | 1 | zhaolaoshi
2 | lisi | 2 | 2 | qianlaoshi
1 | zhangsan | 3 | 3 | sunlaoshi
| | | 6 | lilaoshi
4 | zhaoliu | 4 | |
(5 行记录)
写法2:
select * from student s full outer join teacher t on s.t_id = t.id;
demo=# select * from student s full outer join teacher t on s.t_id = t.id;
id | s_name | t_id | id | t_name
----+----------+------+----+------------
3 | wangwu | 1 | 1 | zhaolaoshi
2 | lisi | 2 | 2 | qianlaoshi
1 | zhangsan | 3 | 3 | sunlaoshi
| | | 6 | lilaoshi
4 | zhaoliu | 4 | |
(5 行记录)
4.半连接
写法1:
select * from student s where exists (select * from teacher t where s.t_id = t.id) ;
demo=# select * from student s where exists (select * from teacher t where s.t_id = t.id) ;
id | s_name | t_id
----+----------+------
1 | zhangsan | 3
2 | lisi | 2
3 | wangwu | 1
(3 行记录)
写法2:
select * from student s where s.t_id in (select id from teacher t) ;
demo=# select * from student s where s.t_id in (select id from teacher t) ;
id | s_name | t_id
----+----------+------
1 | zhangsan | 3
2 | lisi | 2
3 | wangwu | 1
(3 行记录)
5.反半连接
写法1:
select * from student s where not exists (select * from teacher t where s.t_id = t.id) ;
demo=# select * from student s where not exists (select * from teacher t where s.t_id = t.id) ;
id | s_name | t_id
----+---------+------
4 | zhaoliu | 4
(1 行记录)
写法2:
select * from student s where s.t_id not in (select id from teacher t) ;
demo=# select * from student s where s.t_id not in (select id from teacher t) ;
id | s_name | t_id
----+---------+------
4 | zhaoliu | 4
(1 行记录)
三、数据库连接方法:
1.嵌套循环连接
(1)嵌套循环连接
嵌套循环连接是最基础的连接操作,任何连接条件都可以使用这种连接方式,但这种连接方式代价过高,因此PG中很少使用这种连接方式,更多的会使用以下几种嵌套循环连接的变种。
(2)物化嵌套循环连接
嵌套循环连接每读取一条左表(外表)中的元组时,都需要扫描右表(内表)中的所有元组,为每条外表记录做内表全扫描,这个过程代价高昂,
PG支持对内表做临时物化,并存储在内存或者临时文件中,在处理内表元组时,临时元组比缓冲区管理器更为高效,特别是内表比较小的时候,
可以全部载入内存时,我们将这种连接方式称之为物化嵌套循环连接
demo=# explain (analyze , buffers) select * from student s , teacher t ;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=0.00..9714.75 rows=774000 width=128) (actual time=0.014..0.020 rows=16 loops=1)
Buffers: shared hit=2
-> Seq Scan on teacher t (cost=0.00..19.00 rows=900 width=62) (actual time=0.007..0.007 rows=4 loops=1)
Buffers: shared hit=1
-> Materialize (cost=0.00..22.90 rows=860 width=66) (actual time=0.001..0.002 rows=4 loops=4)
Buffers: shared hit=1
-> Seq Scan on student s (cost=0.00..18.60 rows=860 width=66) (actual time=0.002..0.003 rows=4 loops=1)
Buffers: shared hit=1
Planning Time: 0.045 ms
Execution Time: 0.037 ms
(10 行记录)
(3)外表索引嵌套循环连接
如果右表(内表)上有索引,且该索引能用于搜索满足连接条件的元组,那么计划器会为考虑使用索引进行直接搜索,以代替顺序扫描。
这种叫作索引嵌套循环连接
set enable_seqscan to off;
set enable_hashjoin to off;
set enable_mergejoin to off;
create index teacher_id_idx on teacher(id);
reindex table teacher;
demo=# explain (analyze , buffers) select * from student s , teacher t where s.t_id = t.id and t.id = 1;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=10000000000.13..10000000009.21 rows=1 width=128) (actual time=0.013..0.014 rows=1 loops=1)
Buffers: shared hit=3
-> Seq Scan on student s (cost=10000000000.00..10000000001.05 rows=1 width=66) (actual time=0.006..0.007 rows=1 loops=1)
Filter: (t_id = 1)
Rows Removed by Filter: 3
Buffers: shared hit=1
-> Index Scan using teacher_id_idx on teacher t (cost=0.13..8.15 rows=1 width=62) (actual time=0.004..0.005 rows=1 loops=1)
Index Cond: (id = 1)
Buffers: shared hit=2
Planning Time: 0.119 ms
Execution Time: 0.031 ms
(11 行记录)
(4)外表索引扫描物化嵌套循环连接
在索引嵌套循环连接的定义基础上,将内表(右表)物化,注:内表需要有索引
set enable_seqscan to off;
create index teacher_id_idx on teacher(id);
reindex table teacher;
demo=# explain (analyze , buffers) select * from student s inner join teacher t on s.t_id = t.id and t.id <=6;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=10000000000.13..10000000009.25 rows=1 width=128) (actual time=0.016..0.021 rows=3 loops=1)
Join Filter: (s.t_id = t.id)
Rows Removed by Join Filter: 13
Buffers: shared hit=3
-> Seq Scan on student s (cost=10000000000.00..10000000001.04 rows=4 width=66) (actual time=0.005..0.005 rows=4 loops=1)
Buffers: shared hit=1
-> Materialize (cost=0.13..8.15 rows=1 width=62) (actual time=0.001..0.002 rows=4 loops=4)
Buffers: shared hit=2
-> Index Scan using teacher_id_idx on teacher t (cost=0.13..8.15 rows=1 width=62) (actual time=0.004..0.005 rows=4 loops=1)
Index Cond: (id <= 6)
Buffers: shared hit=2
Planning Time: 0.173 ms
Execution Time: 0.041 ms
(13 行记录)
(5)外表索引扫描索引嵌套循环连接
在索引嵌套循环连接的基础上,外表(左表)和内表(右表)上都有索引,且索引可以用于连接条件
set enable_seqscan to off;
set enable_hashjoin to off;
set enable_mergejoin to off;
create index student_tid_idx on student(t_id);
create index teacher_id_idx on teacher(id);
reindex table student;
reindex table teacher;
demo=# explain (analyze , buffers) select * from student s inner join teacher t on s.t_id = t.id and t.id <=6;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=0.26..16.31 rows=1 width=128) (actual time=0.013..0.019 rows=3 loops=1)
Buffers: shared hit=9
-> Index Scan using teacher_id_idx on teacher t (cost=0.13..8.15 rows=1 width=62) (actual time=0.006..0.007 rows=4 loops=1)
Index Cond: (id <= 6)
Buffers: shared hit=2
-> Index Scan using student_tid_idx on student s (cost=0.13..8.15 rows=1 width=66) (actual time=0.001..0.001 rows=1 loops=4)
Index Cond: (t_id = t.id)
Buffers: shared hit=7
Planning Time: 0.242 ms
Execution Time: 0.038 ms
(10 行记录)
2.归并连接
(1)归并连接
内外表按照连接条件进行排序后,再进行连接,与嵌套循环连接不同的是,归并连接只适用于自然连接与等值连接
set enable_hashjoin to off;
set enable_mergejoin to on;
set enable_seqscan to on;
demo=# explain (analyze , buffers) select * from student s, teacher t where s.t_id = t.id and t.id > 1;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
Merge Join (cost=2.15..2.21 rows=3 width=29) (actual time=0.017..0.019 rows=2 loops=1)
Merge Cond: (s.t_id = t.id)
Buffers: shared hit=2
-> Sort (cost=1.08..1.09 rows=4 width=15) (actual time=0.008..0.009 rows=4 loops=1)
Sort Key: s.t_id
Sort Method: quicksort Memory: 25kB
Buffers: shared hit=1
-> Seq Scan on student s (cost=0.00..1.04 rows=4 width=15) (actual time=0.004..0.004 rows=4 loops=1)
Buffers: shared hit=1
-> Sort (cost=1.07..1.08 rows=3 width=14) (actual time=0.005..0.005 rows=3 loops=1)
Sort Key: t.id
Sort Method: quicksort Memory: 25kB
Buffers: shared hit=1
-> Seq Scan on teacher t (cost=0.00..1.05 rows=3 width=14) (actual time=0.003..0.003 rows=3 loops=1)
Filter: (id > 1)
Rows Removed by Filter: 1
Buffers: shared hit=1
Planning Time: 0.112 ms
Execution Time: 0.038 ms
(19 行记录)
(2)物化归并
在归并连接定义的基础上,将内表(右表)物化的归并
(3)外表索引扫描归并
归并连接定义的基础上,外表有索引,且索引适用于连接条件
set enable_seqscan to off;
create index teacher_id_idx on teacher(id);
reindex table teacher;
demo=# explain (analyze , buffers) select * from student s , teacher t where s.t_id = t.id and t.id>1;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------
Merge Join (cost=10000000001.21..10000000009.30 rows=3 width=29) (actual time=0.017..0.020 rows=2 loops=1)
Merge Cond: (s.t_id = t.id)
Buffers: shared hit=3
-> Sort (cost=10000000001.08..10000000001.09 rows=4 width=15) (actual time=0.009..0.009 rows=4 loops=1)
Sort Key: s.t_id
Sort Method: quicksort Memory: 25kB
Buffers: shared hit=1
-> Seq Scan on student s (cost=10000000000.00..10000000001.04 rows=4 width=15) (actual time=0.004..0.005 rows=4 loops=1)
Buffers: shared hit=1
-> Index Scan using teacher_id_idx on teacher t (cost=0.13..12.18 rows=3 width=14) (actual time=0.004..0.004 rows=3 loops=1)
Index Cond: (id > 1)
Buffers: shared hit=2
Planning Time: 0.122 ms
Execution Time: 0.042 ms
(14 行记录)
(4)外表索引扫描物化归并
在外表索引扫描归并连接的基础定义上,将内表物化的连接
(5)外表索引扫描索引归并连接
在外表索引扫描归并连接的基础上,内表也有索引,且索引可以用于连接条件
create index teacher_id_idx on teacher(id);
create index student_tid_idx on student(t_id);
reindex table teacher;
reindex table student;
demo=# explain (analyze , buffers) select * from student s , teacher t where s.t_id = t.id and t.id>1;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------
Merge Join (cost=0.26..20.40 rows=3 width=29) (actual time=0.010..0.013 rows=2 loops=1)
Merge Cond: (s.t_id = t.id)
Buffers: shared hit=4
-> Index Scan using student_tid_idx on student s (cost=0.13..12.19 rows=4 width=15) (actual time=0.003..0.004 rows=4 loops=1)
Buffers: shared hit=2
-> Index Scan using teacher_id_idx on teacher t (cost=0.13..12.18 rows=3 width=14) (actual time=0.003..0.003 rows=3 loops=1)
Index Cond: (id > 1)
Buffers: shared hit=2
Planning Time: 0.269 ms
Execution Time: 0.033 ms
(10 行记录)
3.散列连接
(1)内存散列连接
与归并连接类似,散列连接只能适用于自然连接与等值连接,内存散列连接是在work_mem中处理,散列表区域被称为处理批次,一个处理批
次会有多少散列槽,被称为桶,桶的数量由nodeHash.c中定义的ExecChooseHashTableSize函数确定,且桶的数量总是2的整数次幂
set enable_hashjoin to on;
set enable_mergejoin to on;
set enable_seqscan to on;
demo=# explain (analyze , buffers) select * from student s, teacher t where s.t_id = t.id;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
Hash Join (cost=1.09..2.19 rows=4 width=29) (actual time=0.020..0.023 rows=3 loops=1)
Hash Cond: (s.t_id = t.id)
Buffers: shared hit=2
-> Seq Scan on student s (cost=0.00..1.04 rows=4 width=15) (actual time=0.007..0.008 rows=4 loops=1)
Buffers: shared hit=1
-> Hash (cost=1.04..1.04 rows=4 width=14) (actual time=0.006..0.007 rows=4 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
Buffers: shared hit=1
-> Seq Scan on teacher t (cost=0.00..1.04 rows=4 width=14) (actual time=0.002..0.003 rows=4 loops=1)
Buffers: shared hit=1
Planning Time: 0.067 ms
Execution Time: 0.042 ms
(12 行记录)
(2)带倾斜的混合散列连接
在内存散列定义的基础只上,如果内表的元组无法全部载入内存单个处理批次时,PG就用创建多个批次,只工作区中只分配一个批次,其它批次
都以临时文件的形式创建,属于某个批次的元组将通过临时元组存储功能写入相应的文件中
KingbaseES 数据库连接的更多相关文章
- KingbaseES 数据库连接断开问题排查思路
用户在使用数据库过程中,经常会发现如果会话空闲一段时间,会话有可能断开,需要重连.这个问题影响因素很多,包括数据库参数设置.操作系统参数.防火墙等.以下介绍KingbaseES针对该问题的排查思路. ...
- KingbaseES V8R3集群管理维护案例之---集群迁移单实例架构
案例说明: 在生产中,需要将KingbaseES V8R3集群转换为单实例架构,可以采用以下方式快速完成集群架构的迁移. 适用版本: KingbaseES V8R3 当前数据库版本: TEST=# s ...
- KingbaseES OOM 可能原因汇总
背景 不久前,遇到过一个问题.KingbaseES数据库主机系统触发OOM现象是数据库进程被KILL, 数据库进入crash然后restart(when restart_after_crash=on) ...
- KingbaseES ksqlrc文件介绍
ksqlrc文件作用 ksql在连接到数据库后但在接收正常的命令之前,会尝试读取并执行该文件中的命令,如果加上-X参数,则跳过该文件. 系统级的启动文件是ksqlrc,文件在安装好的KingbaseE ...
- KingbaseES R6 集群一键修改集群和数据库参数测试案例
案例说明: 集群环境修改集群或数据库参数,需要在每个node上都要修改,在每个节点而执行修改操作,容易出现漏改或节点上参数不一致等错误:在KingbaseES V8R6的集群中增加了,一键修改参数 ...
- KingbaseES R6 集群repmgr witness 手工配置案例
使用见证服务器: 见证服务器是一个正常的KingbaseES实例,不是流复制群集的一部分; 其目的是,如果发生故障转移情况,则提供证明它是主服务器本身不可用的证据,而不是例如在不同物理位置之间的网络分 ...
- jdbc访问KingbaseES数据库SocketTimeoutException Read timed out
jdbc访问KingbaseES数据库发生异常:SocketTimeoutException Read timed out 一.异常现象: 应用显示ERROR信息: Caused By: java.n ...
- Java数据库连接技术——JDBC
大家好,今天我们学习了Java如何连接数据库.之前学过.net语言的数据库操作,感觉就是一通百通,大同小异. JDBC是Java数据库连接技术的简称,提供连接各种常用数据库的能力. JDBC API ...
- .NET跨平台之旅:数据库连接字符串写法引发的问题
最近在一个ASP.NET Core站点中遇到一个奇怪问题.当用dotnet run命令启动站点后,开始的一段时间请求执行速度超慢,有时要超过20秒,有时甚至超过1分钟,日志中会记录这样的错误: Sys ...
- Entity Framework 6 Recipes 2nd Edition(12-3)译 -> 数据库连接日志
12-3. 数据库连接日志 问题 你想为每次与数据库的连接和断开记录日志 解决方案 EF为DbContext的连接公开了一个StateChange 事件.我们需要处理这个事件, 为每次与数据库的连接和 ...
随机推荐
- 一键部署Home Assistant ubuntu 20.4.3 树莓派3b+脚本
树莓派3b+安装好 Ubuntu Server 20.04.3 LTS 32bit 后即可适用此脚本,其他版本树莓派/系统可能需要微调脚本*为方便一些未知/已知错误排查 脚本存在冗余部分,足够了解 ...
- win32 - WriteConsoleA 的使用
#include <Windows.h> #include <stdio.h> #pragma warning(disable:4996) void PasswordCheck ...
- Redis集群单机环境搭建
概述 目标:在单台物理机上搭建3主3从共6个节点的Redis集群. 版本:Redis 6.2.4 系统:Ubuntu 18.04 Desktop(IP地址:192.168.100.247) 准备工作 ...
- 微信小程序:接手项目,修bug
好家伙, 问题描述如下: 小程序主界面,选择快速上传会议记录 选择快速 其中,没有2022-2023第二学期,所以,新的会议记录无法上传 于是,我自愿修复这个bug 由于我们没有产品文档 我只能由 ...
- 第一百一十二篇: JS数组Array(一)数组基本用法
好家伙, 1.数组 Array应该就是ECMAScript中最常用的类型了.ECMAScript数组跟其他编程语言的数组有很大区别. 跟其他语言中的数组一样,ECMAScript 数组也是一组有序 ...
- 【Azure Redis 缓存 Azure Cache For Redis】Redis支持的版本及不同版本迁移风险
问题描述 1. Azure Redis缓存支持的版本包括4.0以及6.0(预览) 这种情形下,可以使用PaaS服务提供的 Azure Redis 缓存(4.0版本).Azure Redis对6.0的支 ...
- 「实操」适配 NebulaGraph 新版本与压测实践
本文来自邦盛科技-知识图谱团队-繁凡,本文以 NebulaGraph v3.1.0 为例. 前言 NebulaGraph v3.1 版本已经发布有一段时间了,但是我们的项目之前是基于 v2.6.1 版 ...
- 微信小程序开发:页面分享卡片、风格选择、通道启用等可配置
上文说到,我们部署了定时任务,但是有个地方忘记在上文写了,这里补上,就是定时任务的超时时间问题,超时时间有7200秒: 我们改成7100秒: 再把云函数调用的云对象的超时时间也改下: 超时时间多一点, ...
- vscode 提取扩展时出错 XHR failed
vscode 提取扩展时出错 XHR failed 起因 vscode 安装 Bracket Pair Color DLW 插件,商店打不开了 解决方案 打开 hosts 添加 13.107.42.1 ...
- 学习笔记-涛讲F#(基础 II)
目录 处理一堆数 组织代码(命名空间.模块) 使用联合重命名类型 类必须显式转换成接口 对象表达式 递归函数 CPS解决堆栈溢出 扩展一个类型 静态解析的类型参数 ref变量的实现原理及应用 F#资源 ...