本文分享自华为云社区《【SQL优化】为什么有时候无法走执行性能更优的hashjoin》,作者: leapdb。

1. hash join通常优于nestloop join

通常nestloop join的复杂度是O(N方),hash join时间复杂度是O(N),所以我们一般倾向于使用hash join。
 
在SQL脚本调优过程中通常有两种方式,强制走hash join方式:

1. 在session级关闭nestloop方式,set enable_nestloop to off;

2. 在SQL中通过 /*+ hashjoin(a b) */ 方式,让a和b表走hash join;
 
CREATE DATABASE test_td WITH DBCOMPATIBILITY='td';

create table dim_day(day_code char(8));
create table dwr_rpo as select current_date - 1 as day_code; --返回了date类型 test_td=# \d+ dwr_rpo
Table "public.dwr_rpo"
Column | Type | Modifiers | Storage | Stats target | Description
----------+------+-----------+---------+--------------+-------------
day_code | date | | plain | |
Has OIDs: no
Distribute By: ROUND ROBIN
Location Nodes: ALL DATANODES
Options: orientation=row, compression=no explain select *
from dwr_rpo a
left join dim_day c
on c.day_code = a.day_code; id | operation | E-rows | E-distinct | E-memory | E-width | E-costs
---+----------------------------------------------+---------+------------+----------+---------+--------------
1 | -> Streaming (type: GATHER) | 1310148 | | | 1694 | 279235196.70
2 | -> Nested Loop Left Join (3, 4) | 1310148 | | 1MB | 1694 | 279229682.93
3 | -> Seq Scan on dwr_rpo a | 1310148 | | 1MB | 1676 | 46589.16
4 | -> Materialize | 109575 | | 16MB | 22 | 3747.76
5 | -> Streaming(type: BROADCAST) | 109575 | | 2MB | 22 | 3565.14
6 | -> Seq Scan on dim_day c | 36525 | | 1MB | 22 | 272.75 Predicate Information (identified by plan id)
-----------------------------------------------------------------------------
2 --Nested Loop Left Join (3, 4)
Join Filter: ((c.day_code)::timestamp without time zone = a.day_code)

可是,以上SQL无论用哪种方式都走不上hash join。我们需要看一下,join两端的数据类型是否支持hash比较。
 
1. 为什么有时候无法走执行性能更优的hashjoin

不同数据类型计算hash函数不同,互不兼容的数据类型无法进行hash比较。

2. 为什么hashjoin秒级,nestloop需要两个小时

nestloop复杂度:131w * 10w = 1310亿

hashjoin复杂度:131w

所以两种方式性能差距很大。
 
3. 为什么有类型转换,还不能hash join

看似类型相近,但由于两端的精度,格式,有无时区等不一样,无法认为直接相等。

4. 都哪些数据类型间的join不支持hash?
select oprname,oprkind,oprcanhash,
(select typname from pg_type where oid=oprleft) oprleft,
(select typname from pg_type where oid=oprright) oprright
from pg_operator
where oprname='=' and oprcanhash='f'; oprname | oprkind | oprcanhash | oprleft | oprright
---------+---------+------------+---------------+---------------
= | b | f | xid | int8
= | b | f | xid32 | int4
= | b | f | tid | tid
= | b | f | box | box
= | b | f | path | path
= | b | f | tinterval | tinterval
= | b | f | money | money
= | b | f | circle | circle
= | b | f | lseg | lseg
= | b | f | line | line
= | b | f | bit | bit
= | b | f | varbit | varbit
= | b | f | date | timestamp
= | b | f | date | timestamptz
= | b | f | timestamp | date
= | b | f | timestamptz | date
= | b | f | timestamp | timestamptz
= | b | f | timestamptz | timestamp
= | b | f | tsvector | tsvector
= | b | f | tsquery | tsquery
= | b | f | record | record
= | b | f | hll | hll
= | b | f | hll_hashval | hll_hashval
= | b | f | roaringbitmap | roaringbitmap
(24 rows)
 
主要是timestamp, timestamptz, date间互相join是无法走hash。其它数据类型不常见。
 
开发建议:join两端的数据类型尽量一致或互相兼容。
 
5. 为什么 oracle 兼容模式没有问题,td兼容模式有问题?

current_date 在TD兼容模式下为date类型;

current_date 在Oracle兼容模式下为timestamp类型;

点击关注,第一时间了解华为云新鲜技术~

如何强制SQL走性能更优的hash join的更多相关文章

  1. sql server 性能调优 资源等待之网络I/O

    原文:sql server 性能调优 资源等待之网络I/O 一.概述 与网络I/O相关的等待的主要是ASYNC_NETWORK_IO,是指当sql server返回数据结果集给客户端的时候,会先将结果 ...

  2. sql server 性能调优之 资源等待PAGELATCH

    一.概述 在前几章介绍过 sql server 性能调优资源等待之PAGEIOLATCH,PAGEIOLATCH是出现在sql server要和磁盘作交互的时候,所以加个IO两个字.这次来介绍PAGE ...

  3. sql server 性能调优之 CPU消耗最大资源分析1 (自sqlserver服务启动以后)

    一. 概述 上次在介绍性能调优中讲到了I/O的开销查看及维护,这次介绍CPU的开销及维护, 在调优方面是可以从多个维度去发现问题如I/O,CPU,  内存,锁等,不管从哪个维度去解决,都能达到调优的效 ...

  4. CPU开销sql server 性能调优

    sql server 性能调优 CPU开销分析 一. 概述 上次在介绍性能调优中讲到了I/O的开销查看及维护,这次介绍CPU的开销及维护, 在调优方面是可以从多个维度去发现问题如I/O,CPU, 内存 ...

  5. 【目录】sql server 性能调优

    随笔分类 - sql server 性能调优 sql server 性能调优之 资源等待之网络I/O 摘要: 一.概述 与网络I/O相关的等待的主要是ASYNC_NETWORK_IO,是指当sql s ...

  6. PHP日志扩展 SeasLog-1.6.8, 性能更优

    SeasLog-1.6.8 发布了,性能更优. 改进日志: 1.6.8: 优化内存使用和性能,修复已知Bug. - Fixed issue #97 PHP5.* Cached Block. - Fix ...

  7. SQL server 性能调优

    转自: http://www.cnblogs.com/MR_ke/archive/2010/08/25/1807856.html sql 2005性能调优 SQL Server在运行一段时间,随着数据 ...

  8. SQL Server 性能调优培训引言

    原文:SQL Server 性能调优培训引言 大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤 ...

  9. sql server 性能调优之 资源等待 LCk

    一.  概述 这次介绍实例级别资源等待LCK类型锁的等待时间,关于LCK锁的介绍可参考 “sql server 锁与事务拨云见日”.下面还是使用sys.dm_os_wait_stats 来查看,并找出 ...

  10. sql server性能调优

    转自:https://www.cnblogs.com/woodytu/tag/%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98%E5%9F%B9%E8%AE%AD/defaul ...

随机推荐

  1. CF276C

    题目简化和分析: 属于一种贪心思维,我们想如果要使得和最大,那么就必须保证最大的数乘的次数越多越好,并且排序没有限制,快速累加每个位置出现的次数,所以应该使用线段树差分. 然后排序最大乘最大累加. S ...

  2. CentOS7调整分区大小

    前言 部署CentOS7的时候分配的动态扩充虚拟磁盘,共1T大小,在安装Centos时默认分区,系统仅给/分配50G,而大量空间都挂载到/home下,最近CentOS7使用中发现空间已不足够,所以就想 ...

  3. 洛谷P1990

    这是一道dp的题,好像也不算dp.需要递推,感觉能训练思维!!!很棒的一道题. 覆盖墙壁 关于这道题的分析 状态表示:f[i][0]表示前i列全部填满的所有方案,f[i][1]表示前i列全部填满缺一个 ...

  4. java——1.变量和数据类型

    变量和数据类型 字符.字节.位之间的关系 1.字符:人类可以阅读的文本内容最小单位 ​ 字符编码:utf-8,gbk 2.字节:1字符=2字节:1字符=4字节 3.位:1字节=8位 位指的是二进制位, ...

  5. 使用visualvm远程监控JVM

    参考:http://blog.sina.com.cn/s/blog_4e90b3ba0100muco.html 1.首先要修改JDK中JMX服务的配置文件,以获得相应的权限: 在jdk-1.6.0_2 ...

  6. 3款免费又好用的 Docker 可视化管理工具

    前言 Docker提供了命令行工具(Docker CLI)来管理Docker容器.镜像.网络和数据卷等Docker组件.我们也可以使用可视化管理工具来更方便地查看和管理Docker容器.镜像.网络和数 ...

  7. Centos7.5镜像获取

    Centos.7.5镜像可从以下地址获取 镜像源地址:https://mirrors.tuna.tsinghua.edu.cn/ 1.下拉找到cc目录下的centos-vault 2.点击进入下一级目 ...

  8. .NET周刊【11月第1期 2023-11-09】

    国内文章 C#/.NET/.NET Core优秀项目和框架2023年10月简报 https://www.cnblogs.com/Can-daydayup/p/17804085.html 本文主要介绍了 ...

  9. day2-JS基础&流程控制

    typora-root-url: img 自增自减运算符 1.基本使用 内置提供 ++.--运算符 是用于将变量本身进行加1或者减1操作 // 1.基本使用 var i = 10; i++;//等价于 ...

  10. 【Javaweb】Servlet* | 请求重定向【🖤🖤】

    请求重定向的含义 请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说.我给你一些地址,你去新地址访问,叫请求重定向(因为之前的地址可能已经废弃). 请求重定向的实现代码 请求重定向的第一种方 ...