1 实验目的
- 学习并掌握数据库管理系统中查询处理与查询优化的基本知识和方法。
- 通过查询计划执行工具(explain)体会不同优化策略对查询执行性能的影响,掌握基本的查询优化方法。
2 实验平台与工具
- Windows、Linux操作系统
- 数据库管理系统PostgreSQL
3 实验内容与要求
利用PG中的explain工具,对比不同连接算法在SQL查询语句执行中的作用。
- 针对Nested Loop Join,Hash Join,Merge Sort Join三种连接进行比较,可以选择其中两种,也可以选择全部三种参与实验,自行决定。
- 实验采用的数据库及其基本表自行决定。
- 通过实验展现不同情况下(包括大小表、有无索引、不同的连接比较条件)物理优化的效果,对实验步骤及其结果进行必要说明和解释(包括时间代价、存取路径的策略等),最终实现实验目的2的达成。
实验报告
一、实验环境
1. 操作系统:
Windows 10
2. 数据库管理系统软件(含版本号):
PostgreSQL 14
pgAdmin4
二、实验内容及其完成情况
无索引的执行计划
查看索引
在length属性上进行查询
建立索引
创建索引后查询
执行顺序
Buffers参数
And/or
Hash join实现查询与查询计划
案例一(由于这个查询包括强制连接类型等方法,无论怎么执行都使用了hash join而不具备参考性,仅做一个实验记录)
案例二
Nested Loop join实现查询与查询计划
三、实验总结
(可以总结实验中出现的问题以及解决的思路,也可以列出没有解决的问题)
问题1:
问题描述
使用sql shell时找不到要找的关联
问题分析(可能的原因、难点、挑战)
要先从用户跳转到指定的模式下才能访问指定模式下的关联
解决方案
(如该问题没有被解决可以不写具体的解决方案,而给出大致的思路和方向)
在SQL Shell中,可以使用\c schema_name;命令来切换到指定的数据库模式。
问题2:
问题描述
PostgreSQL 查询优化器没有选择使用 Nested Loop Join,而是选择了 Hash Join
对比hash join和nested loop join
Nested Loop Join 比 Hash Join 耗时,可能有以下原因:
- 数据集较大:我在查询dvdrental中film表与film_actor链接后的表中,length>150且actor_id=5的数据就有7000多条,可想这个数据集有多大。如果连接的数据集非常大,而且没有合适的索引,那么使用 Nested Loop Join 就会导致大量的磁盘读写和内存占用,从而影响查询性能。
- 查询条件复杂:该查询链接两个表,有and语句,查询条件要满足:1.film.film_id=film_actor.film_id;2.film_actor.actor_id=5;3.film.length>150;如果查询条件比较复杂,例如涉及多个关联条件或者使用了复杂的函数表达式,那么使用 Nested Loop Join 可能会导致多次循环嵌套,从而影响查询性能。
问题分析(可能的原因、难点、挑战)
postgreSQL 查询优化器没有选择使用 Nested Loop Join,而是选择了 Hash Join,可能是因为 PostgreSQL 认为 Hash Join 更适合当前的查询条件和数据集。
解决方案
(如该问题没有被解决可以不写具体的解决方案,而给出大致的思路和方向)、
可以尝试强制 PostgreSQL 使用 Nested Loop Join 来连接表,方法如下:
在查询语句中添加 SET JOIN_COLLAPSE_LIMIT = 1; 来设置 Nest Loop Join 的优先级。
执行查询语句,此时 PostgreSQL 会优先选择 Nested Loop Join 来连接表。
尝试了,但是它还是使用了Hash join,这是我查到的原因。
一些情况下,Hash Join 可能比 Nested Loop Join 更适合:
连接的数据集非常大,Nested Loop Join 会导致大量的磁盘读写和内存占用,影响查询性能。
连接的列没有索引,使用 Nested Loop Join 可能会导致全表扫描,也会影响查询性能。
连接的列数据分布不均匀,使用 Nested Loop Join 可能会导致连接效率较低,而 Hash Join 可以更好地处理数据分布不均匀的情况。