Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >多表使用use_hash hint,你写对了吗?

多表使用use_hash hint,你写对了吗?

作者头像
老虎刘
发布于 2022-06-22 09:34:49
发布于 2022-06-22 09:34:49
1.7K00
代码可运行
举报
运行总次数:0
代码可运行

oracle的online document里面,对use_hash的hint语法是这样描述的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*+ USE_HASH ( [ @ queryblock ] tablespec [ tablespec ]... ) */

而大部分的开发人员也确实是这样写的: use_hash(a b) ,这个确实没问题。

当关联的表超过2个的时候,写成use_hash(a b c d)有没有问题呢?

我们先来看一个test case,这个案例根据客户真实案例改编,模拟的是在表关联条件复杂的情况下,优化器对表关联后的结果集估值过小,可能使用错误的执行计划,希望通过增加use_hash hint来优化SQL。

--创建4个表

create table tv as select rownum as id,a.* from dba_objects a;

create table tt as select * from tv;

create table tw as select * from tv;

create table tu as select * from tv;

--收集统计信息

exec dbms_stats.gather_table_stats(user,'tw');

exec dbms_stats.gather_table_stats(user,'tt');

exec dbms_stats.gather_table_stats(user,'tu');

exec dbms_stats.gather_table_stats(user,'tv');

SQL:

select /*+ use_hash(v t u w) */

count(*) from tv v,tu u,tw w,tt t

where

t.id=v.id and t.object_name=upper(v.object_name) and

w.id=u.id and

v.created between t.created and t.last_ddl_time and

v.created between u.created and u.last_ddl_time and

t.object_id=w.object_id and w.created=v.created;

真实案例的情况是:SQL正常执行时间3.4分钟,某天TV表delete一些记录后,执行了将近20分钟还没有完成,而其中最重要的变化就是执行计划其中的一个hash join变成了nested loops,虽然hint中已经指定全部表要use_hash。

这个模拟的SQL展示的就是真实案例出现异常的情况。其中一个步骤使用了nested loops,大概要执行4分钟左右才能完(测试时可以cancel),全部hash的执行计划不到1秒。

当前hint生成的执行计划:

这个执行计划出现了nested loops的情况,没有按照hint的指示全部使用hash_join,说明这种hint的写法确实是有问题的。

那么,正确的写法是怎样的呢?

问题的关键在于:

多表的use_hash,一定要配合leading的hint使用。

根据sql的关联条件,我们增加leading的hint再测试一下:

select /*+ leading(v t w u) use_hash(u v t w) */

count(*) from tv v,tu u,tw w,tt t

where

t.id=v.id and t.object_name=upper(v.object_name) and

w.id=u.id and

v.created between t.created and t.last_ddl_time and

v.created between u.created and u.last_ddl_time and

t.object_id=w.object_id and w.created=v.created;

这次,SQL只需要不到1秒时间就能跑出结果了,执行计划也正是我们需要的全部hash join:

在优化器内部生成的标准执行计划outline data中,上面的hint最终被转化成这样:

(有没有注意到,其中leading的第一个表没有做use_hash(V)?

这是因为,有第二个表的use_hash(t)的存在,t表做use_hash(t),跟谁做?当然是和第一个表V)。

结论:

我们在写多表use_hash(use_nl也一样)hint的时候,use_hash的括号里面是可以放多个表(顺序无关),但是一定要结合leading 的hint,才能保证优化器不使用其他的join方式。 leading里面表的顺序非常关键哦,搞错了会带你去见笛卡尔(cartesian join)。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老虎刘谈oracle性能优化 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
执行计划之表连接1:连接树(Join Trees)
阅读官方在线文档无疑是学习Oracle最好的方法,本文参考在线文档介绍表连接以及连接树(Join Trees)。
SQLplusDB
2022/08/19
7350
执行计划之表连接1:连接树(Join Trees)
Oracle优化07-分析及动态采样-直方图
获取准确的段对象(表、表分区、索引等)的分析数据,是CBO存在的基石。所以数据段的分析对于CBO来讲非常的重要。
小小工匠
2021/08/16
3300
常见Oracle HINT的用法
Hint概述 基于代价的优化器是很聪明的,在绝大多数情况下它会选择正确的优化器,减轻了DBA的负担。但有时它也聪明反被聪明误,选择了很差的执行计划,使某个语句的执行变得奇慢无比。
jack.yang
2025/04/05
1490
Oracle优化05-执行计划
如果要分析某条SQL的性能问题,通常来讲,我们首先要看SQL的执行计划,看看SQL的每一步执行计划是否存在问题。
小小工匠
2021/08/16
8550
【DB笔试面试598】在Oracle中,如何得到真实的执行计划?
在Oracle数据库中判断得到的执行计划是否准确,就是看目标SQL是否被真正执行过,真正执行过的SQL所对应的执行计划就是准确的,反之则有可能不准,因此,通过10046事件及如下的几种方式得到的执行计划是最准确的,而从其它方式获取到的执行计划都有可能不准确。
AiDBA宝典
2019/09/29
7810
【DB笔试面试517】在Oracle中,什么是临时表?它有哪些分类?有关临时表需要注意什么?
目前所有使用Oracle作为数据库支撑平台的应用,大部分是数据量比较庞大的系统,即表的数据量级一般情况下都是在百万级以上。当然,在Oracle中创建分区是一种不错的选择,但是当发现应用有多张表关联的时候,并且这些表大部分都比较庞大,而关联的时候发现其中的某一张或者某几张表关联之后得到的结果集非常小,并且查询得到这个结果集的速度非常快,那么这个时候考虑在Oracle中创建“临时表”。
AiDBA宝典
2019/09/29
1.4K0
102-not in和not exists到底选哪个?这个问题有点复杂,但是结论很简单,不要被专家们带偏了。
最近在某平台学习一个关于oracle SQL优化培训课程中,听讲师在讲到not in的知识点时说:“not in的子查询是不等于的关系,不能用索引。跟in使用nested loops可以走索引的执行计划不一样”。 这个说法跟参加老师您的培训时学到的内容不太一样,到底以哪个为准呢?
老虎刘
2023/09/01
7050
102-not in和not exists到底选哪个?这个问题有点复杂,但是结论很简单,不要被专家们带偏了。
sql_profile的使用(一) (r2笔记29天)
今天看了老熊关于sql_profile的讲解,受益匪浅,自己在本机也做了一通,感觉好记性不如烂笔头还是得多总结总测试才能真正理解。 准备的数据如下,创建两个表,一个大,一个小,然后做表分析 SQL> create table t1 as select object_id,object_name from dba_objects where rownum<=50000; Table created. SQL> create table t2 as select * from dba_objects;
jeanron100
2018/03/14
5740
SQL查询太慢?实战讲解YashanDB SQL调优思路
说起SQL调优,不少人认为是个高难度的事情,让人望而却步。但其实在日常的运维过程中,慢SQL却是一个常见的问题,这时大家或多或少会用到一些常用的调优手段,比如加索引、调整执行计划等。
用户10349277
2025/02/26
270
【DB笔试面试582】在Oracle中,什么是绑定变量窥探(上)?
目标SQL若不使用绑定变量,则当具体输入值一旦发生了变化,目标SQL的SQL文本就会随之发生变化,这样Oracle就能很容易地计算出对应Selectivity和Cardinality的值,进而据此来选择执行计划。但对于使用了绑定变量的目标SQL而言,情况就完全不一样了,因为现在无论对应绑定变量的具体输入值是什么,目标SQL的SQL文本都是一模一样的。对于使用了绑定变量的目标SQL而言,Oracle可以选择如下两种方法来决定其执行计划:
AiDBA宝典
2019/09/29
1.6K0
是什么操作把SQL性能提高了6倍多?
优化前,最终返回3096条记录,耗时4146秒(执行时间看第一行中间的timeline):
老虎刘
2022/06/22
3370
是什么操作把SQL性能提高了6倍多?
深入解析:半连接与反连接的原理和等价改写方法
半连接的原理及等价改写 1. 什么是半连接 当两张表进行关联,只返回匹配上的数据并且只会返回一张的表的数据,半连接一般就是指的在子查询中出现 IN 和 EXISTS。 执行计划最常见的有下面的两个: NESTED LOOPS SEMI HASH JOIN SEMI 1.1 NESTED LOOP SEMI 执行步骤: 优化器选择主查询中的表为驱动表; 选择子查询中的表为被驱动表; 把驱动表的每一行根据连接列去被驱动表中去查找匹配的行; 如果在被驱动表中匹配上一个或者多个,则返回驱动表中的数据。 HI
数据和云
2018/03/29
2K0
深入解析:半连接与反连接的原理和等价改写方法
Oracle-表分析和索引分析解读
当表没有做分析的时候,Oracle 会使用动态采样来收集统计信息。 获取准确的段对象(表,表分区,索引等)的分析数据,是CBO存在的基石,CBO的机制就是收集尽可能多的对象信息和系统信息,通过对这些信息进行计算,分析,评估,最终得出一个成本最低的执行计划。
小小工匠
2021/08/16
8610
灌入大量数据后手工采集统计信息的重要性
SQL> create table TBL_STAT as select * from dba_objects where 1<>1; Table created. SQL> create index idx_tbl_stat on tbl_stat (object_id); Index created. SQL> select count(*) from tbl_stat;   COUNT(*) ----------          0
bisal
2019/01/29
3470
【DB笔试面试258】在Oracle中,执行计划里的access和filter有什么区别(上)?
一般而言,access表示这个谓词条件的值将会影响数据的访问路径(表还是索引);filter表示谓词条件的值不会影响数据的访问路劲,只起到过滤的作用。NOT IN或MIN函数等容易产生filter操作。
AiDBA宝典
2019/09/30
1.5K0
【DB笔试面试258】在Oracle中,执行计划里的access和filter有什么区别(上)?
层层升入:SQL极限调优之一次更新操作的N种优化可能
杨廷琨,网名 yangtingkun 云和恩墨技术总监,Oracle ACE Director,ACOUG 核心专家 最近进行了一次更新操作,整个处理和优化的过程很有意思,于是将这个过程记录了下来。 首先描述一下更新的要求:根据远端数据库中几张表的关联结果来刷新本地表中的一个字段的值。如果本地表中记录的ID在远端表关联中可以查询到,则这条记录的相应字段更新为1;如果对应记录在远端无法查询到记录,则这个字段更新为0。 这个需求比较简单,但是被更新的表是物化视图复制的基表,这张表的所有修改都会同步到多个远
数据和云
2018/03/06
1.1K0
层层升入:SQL极限调优之一次更新操作的N种优化可能
SQL查询太慢?实战讲解YashanDB SQL调优思路
本文是Meetup第十期“调优实战专场”的第二篇技术文章,上一篇《高效查询秘诀,解码YashanDB优化器分组查询优化手段》中,我们揭秘了YashanDB分组查询优化秘诀,本文将通过一个案例,助你快速上手YashanDB慢日志功能,精准定位“慢SQL”后进行优化。
用户10349277
2025/02/18
1040
dbms_stats 导入导出表统计信息
      在SQL tuning的过程中,不正确的或者过时的统计信息导致使用不正确的执行计划被采用的情况比比皆是。 当然对于这个情形,我们可以通过收集最新的统计信息来达到优化的目的。而且Oracle之前的统计信息会自动保留。除此之外,我们也可以通过备份的方式来实现导入导出统计信息。本文即使描述的即是该方式,同时并对比了不同统计信息的执行计划,最后给出了一个批量导出统计信息的代码。       有关导入导出统计信息的具体步骤及使用情形可参考: dbms_stats 导入导出 schema 级别统计信息
Leshami
2018/08/13
8090
Oracle优化08-并行执行
在讨论Oracle的性能问题时,通常要假设一个前提,那就是这个系统是OLTP还是OLAP(或者说数据仓库系统)。 只有在这个前提下,讨论一些性能问题才有意义,因为这两类系统太不一样了,甚至很多技术是相悖的。
小小工匠
2021/08/16
4190
按图索骥:SQL中数据倾斜问题的处理思路与方法
数据倾斜即表中某个字段的值分布不均匀,比如有100万条记录,其中字段A中有90万都是相同的值。这种情况下,字段A作为过滤条件时,可能会引起一些性能问题。 本文通过示例分享部分场景的处理方法 未使用绑定变量 使用绑定变量 几种特殊场景 1 测试环境说明 数据库版本:ORACLE 11.2.0.4 新建测试表tb_test: create tablescott.tb_test as select * from dba_objects; 创建索引: create indexscott.idx_tb_test_01
企鹅号小编
2018/01/23
1.1K0
按图索骥:SQL中数据倾斜问题的处理思路与方法
推荐阅读
相关推荐
执行计划之表连接1:连接树(Join Trees)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档