【MogDB】MogDB5.2.0重磅发布第五篇-支持部分ORACLE的HINT

一、背景

ORACLE的SQL优化器非常强大,但是仍然会在某些情况下,ORACLE自动生成的执行计划并不是很好,此时可以通过在SQL中增加HINT来人工控制执行计划应该怎么走。在ORACLE迁移到国产库的过程中,由于部分国产库并不支持ORACLE的HINT名称,因此以前在ORACLE加的这些HINT到了国产库并不生效,导致有些SQL执行变得很慢。一般情况下认为迁移到国产库需要重新进行SQL调优是无可避免的事,但是,如果一套应用系统使用ORACLE迭代开发十几年,积累了大量的SQL,使用了数不清的hint,一次性迁移到国产库,所有SQL都得重新进行性能分析和优化,这对SQL开发人员来说,会是一个巨大的工作量!
MogDB考虑到这种情况,决定采取以对内核影响最少的方式,尽可能多兼容一些Oracle的hint。

二、支持的hint列表

hint名称说明
CARDINALITY映射为rows(#)
FULL映射为TableScan
INDEX_JOIN映射为IndexOnlyScan
INDEX映射为IndexScan
NO_INDEX映射为No_Index
NO_UNNEST映射为No_expand
OPTARAM映射为set
PARALLEL(dop)映射为set(query_dop dop)
QB_NAME映射为BlockName
USE_HASH映射为HashJoin
NO_USE_HASH映射为 no HashJoin
USE_MERGE映射为MergeJoin
NO_USE_MERGE映射为 no MergeJoin
USE_NL映射为NestLoop
NO_USE_NL映射为 no NestLoop
APPEND新增,仅做语法支持,不影响其他同时使用的hint

三、用法示例

DROP SCHEMA IF EXISTS test_oracle_hints CASCADE;
CREATE SCHEMA test_oracle_hints;
SET current_schema='test_oracle_hints';
DROP TABLE IF EXISTS oracle_hints_01;
CREATE TABLE oracle_hints_01(a int, b int);
CREATE INDEX hint01_index on oracle_hints_01(a);
INSERT INTO oracle_hints_01 VALUES (generate_series(1, 1000), generate_series(1, 1000));
ANALYZE oracle_hints_01;
SET smp_thread_cost = 0;-- cardinality hints
explain (costs off) select /*+ cardinality(t1 100) cardinality(t2, 100) cardinality(t1, t2, 100) */ * from oracle_hints_01 t1, oracle_hints_01 t2 where t1.a = t2.a;QUERY PLAN
--------------------------------------------Hash JoinHash Cond: (t1.a = t2.a)->  Seq Scan on oracle_hints_01 t1->  Hash->  Seq Scan on oracle_hints_01 t2
(5 rows)-- full hints
explain (costs off) select /*+ full(t1) */ * from oracle_hints_01 t1 where t1.a = 1;QUERY PLAN     
--------------------------------Seq Scan on oracle_hints_01 t1Filter: (a = 1)
(2 rows)-- index join hints
explain (costs off) select /*+ index_join(t1, hint01_index) */ a from oracle_hints_01 t1 where t1.a > 1;QUERY PLAN                  
----------------------------------------------------------[Bypass]Index Only Scan using hint01_index on oracle_hints_01 t1Index Cond: (a > 1)
(3 rows)-- index hints
explain (costs off) select /*+ index(t1, hint01_index) */ * from oracle_hints_01 t1 where t1.a > 1;QUERY PLAN                
-----------------------------------------------------[Bypass]Index Scan using hint01_index on oracle_hints_01 t1Index Cond: (a > 1)
(3 rows)explain (costs off) select /*+ no_index(t1, hint01_index) */ * from oracle_hints_01 t1 where t1.a = 1;QUERY PLAN          
-----------------------------------------Bitmap Heap Scan on oracle_hints_01 t1Recheck Cond: (a = 1)->  Bitmap Index Scan on hint01_indexIndex Cond: (a = 1)
(4 rows)-- no_unnest hints
explain (costs off) select * from oracle_hints_01 t1 where t1.a in (select /*+ no_unnest() */ t2.a from oracle_hints_01 t2);QUERY PLAN         
----------------------------------------Seq Scan on oracle_hints_01 t1Filter: (hashed SubPlan 1)SubPlan 1->  Seq Scan on oracle_hints_01 t2
(4 rows)-- opt params hints
explain (costs off) select /*+ opt_param('query_dop', 4) */ a from oracle_hints_01 t1 where t1.a > 1;QUERY PLAN         
----------------------------------------Streaming(type: LOCAL GATHER dop: 1/4)->  Seq Scan on oracle_hints_01 t1Filter: (a > 1)
(3 rows)explain (costs off) select /*+ opt_param(query_dop, 4) */ a from oracle_hints_01 t1 where t1.a > 1;QUERY PLAN         
----------------------------------------Streaming(type: LOCAL GATHER dop: 1/4)->  Seq Scan on oracle_hints_01 t1Filter: (a > 1)
(3 rows)-- parallel hints
explain (costs off) select /*+ parallel(4) */ a from oracle_hints_01 t1 where t1.a > 1;QUERY PLAN         
----------------------------------------Streaming(type: LOCAL GATHER dop: 1/4)->  Seq Scan on oracle_hints_01 t1Filter: (a > 1)
(3 rows)-- qb_name hints
explain (costs off) select /*+nestloop(t1 tt) */ * from oracle_hints_01 t1 where t1.a in (select /*+ qb_name(tt) */ t2.a from oracle_hints_01 t2 group by t2.a);QUERY PLAN                   
-----------------------------------------------------------Nested Loop->  HashAggregateGroup By Key: t2.a->  Seq Scan on oracle_hints_01 t2->  Index Scan using hint01_index on oracle_hints_01 t1Index Cond: (a = t2.a)
(6 rows)-- join hints
explain (costs off) select /*+ use_hash(t1, t2) */ * from oracle_hints_01 t1, oracle_hints_01 t2 where t1.a = t2.a;QUERY PLAN           
--------------------------------------------Hash JoinHash Cond: (t1.a = t2.a)->  Seq Scan on oracle_hints_01 t1->  Hash->  Seq Scan on oracle_hints_01 t2
(5 rows)explain (costs off) select /*+ no_use_hash(t1, t2) */ * from oracle_hints_01 t1, oracle_hints_01 t2 where t1.a = t2.a;QUERY PLAN                   
-----------------------------------------------------------Merge JoinMerge Cond: (t1.a = t2.a)->  Index Scan using hint01_index on oracle_hints_01 t1->  Index Scan using hint01_index on oracle_hints_01 t2
(4 rows)explain (costs off) select /*+ use_merge(t1, t2) */ * from oracle_hints_01 t1, oracle_hints_01 t2 where t1.a = t2.a;QUERY PLAN                   
-----------------------------------------------------------Merge JoinMerge Cond: (t1.a = t2.a)->  Index Scan using hint01_index on oracle_hints_01 t1->  Index Scan using hint01_index on oracle_hints_01 t2
(4 rows)explain (costs off) select /*+ no_use_merge(t1, t2) */ * from oracle_hints_01 t1, oracle_hints_01 t2 where t1.a = t2.a;QUERY PLAN           
--------------------------------------------Hash JoinHash Cond: (t1.a = t2.a)->  Seq Scan on oracle_hints_01 t1->  Hash->  Seq Scan on oracle_hints_01 t2
(5 rows)explain (costs off) select /*+ use_nl(t1, t2) */ * from oracle_hints_01 t1, oracle_hints_01 t2 where t1.a = t2.a;QUERY PLAN                   
-----------------------------------------------------------Nested Loop->  Seq Scan on oracle_hints_01 t1->  Index Scan using hint01_index on oracle_hints_01 t2Index Cond: (a = t1.a)
(4 rows)explain (costs off) select /*+ no_use_nl(t1, t2) */ * from oracle_hints_01 t1, oracle_hints_01 t2 where t1.a = t2.a;QUERY PLAN           
--------------------------------------------Hash JoinHash Cond: (t1.a = t2.a)->  Seq Scan on oracle_hints_01 t1->  Hash->  Seq Scan on oracle_hints_01 t2
(5 rows)DROP SCHEMA test_oracle_hints;

四、差异点

对于这些和ORACLE相同名称的HINT,MogDB仍然有一些差异。
在MogDB 5.2.0版本中:

  • CARDINALITY 不支持CARDINALITY(n)的形式,即必须指定表或者表别名
  • PARALLEL 不支持PARALLEL(t n)的形式,即不能指定单表的并行度
  • USE_HASH 不支持只填写一个表,至少需要两个表
  • use_hash(t1,t2,t3,t4) 可以直接控制连接顺序,即 (t1(t2 (t3 t4)))
  • leading保留原本MogDB支持的用法,未做修改,比较明显的一个差异就是MogDB的leading里不能只放一个表

五、总结

ORACLE里支持的hint其实远不止这些,但由于底层原理上存在一些差异,任何非ORACLE数据库都不可能做到和ORACLE的hint全兼容,每种数据库都应该有自己特有的SQL优化器。因此,就算做了一些ORACLE的兼容HINT,也不能说性能就能和ORACLE一样,如果想要得到最佳性能表现,仍然离不开数据库内核自身的优化能力。

  • 本文作者: DarkAthena
  • 本文链接: https://www.darkathena.top/archives/mogdb-5.2.0-support-oracle-sql-hint
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/59127.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

U盘引导丢失问题的处理办法

项目背景:在使用自制的u盘系统的时候经常遇到引导丢失的问题,那么咱们怎么解决这个问题呢,首先第一步通过手动引导u盘 进入系统,同时再进行引导区的修复这样u盘系统就可以正常工作了。 1 进入grub 的提示符下面,首先…

Caffeine 手动策略缓存 put() 方法源码解析

BoundedLocalManualCache put() 方法源码解析 先看一下BoundedLocalManualCache的类图 com.github.benmanes.caffeine.cache.BoundedLocalCache中定义的BoundedLocalManualCache静态内部类。 static class BoundedLocalManualCache<K, V> implements LocalManualCache&…

树莓派开发相关知识四 传感器-测距C语言版本

1、封装调用函数 #include <stdio.h> #include <time.h> #include "wiringPi.h"void initmode(int trig,int echo) {wiringPiSetupGpio();pinMode(trig,OUTPUT);digitalWrite(trig,LOW);pinMode(echo,INPUT); }double get_distance(int trig,int echo) …

《Qwen2-VL》论文精读【上】:发表于2024年10月 Qwen2-VL 迅速崛起 | 性能与GPT-4o和Claude3.5相当

1、论文地址Qwen2-VL: Enhancing Vision-Language Model’s Perception of the World at Any Resolution 2、Qwen2-VL的Github仓库地址 该论文发表于2024年4月&#xff0c;是Qwen2-VL的续作&#xff0c;截止2024年11月&#xff0c;引用数24 文章目录 1 论文摘要2 引言3 实验3.…

StandardThreadExecutor源码解读与使用(tomcat的线程池实现类)

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java源码解读-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 目录 1.前言 2.线程池基础知识回顾 2.1.线程池的组成 2.2.工作流程 2…

Spring学习笔记_21——循环依赖

循环依赖 1. 介绍 在Spring中的循环依赖就是指一个或者多个Bean之间存在着互相依赖的关系&#xff0c;并且形成了循环调用。 例如&#xff1a;在Spring中&#xff0c;Bean-A依赖Bean-B&#xff0c;Bean-B又依赖Bean-A&#xff0c;Bean-A和Bean-B之间就形成了相互依赖的关系。…

前端埋点与监控最佳实践:从基础到全流程实现.

前端埋点与监控最佳实践&#xff1a;从基础到全流程实现 大纲 我们会从以下三个方向来讲解埋点与监控的知识&#xff1a; 什么是埋点&#xff1f;什么是监控&#xff1f; JS 中实现监控的核心方案 写一个“相对”完整的监控实例 一、什么是埋点&#xff1f;什么是监控&am…

asp.net老项目运维,出现的问题4

此次问题出现在sqlserver的select in(单号1,单号2........) 语句&#xff0c;项目中使用这个语句批量查询单号&#xff0c;最多的情况也就几十个&#xff0c;返回结果速度上用户还能接受。 但是最近有了新业务&#xff0c;select数据量大大提升&#xff0c;有的情况in()中的单…

【缓存与加速技术实践】NoSQL之Redis部署安装与基础命令

文章目录 关系型数据库与非关系型数据库关系型数据库SQL定义SQL语句主流产品 非关系型数据库NoSQL定义主流产品 区别数据存储方式不同扩展方式不同对事务性的支持不同应用场景结构对比 补充 RedisRedis 的特点与优势Redis 的使用场景哪些数据适合放入缓存中&#xff1f;Redis 为…

MATLAB-数学建模-无约束规划求解方法(非线性规划)

MATLAB-数学建模-无约束规划求解方法&#xff08;非线性规划&#xff09; fminbnd函数 其功能是求取固定区间内单变量函数的最小值&#xff0c;也就是一元函数的最小值问题。其数学模型为 minf(x),x1<x<x1 式中&#xff0c;x,x1,x2 均为标量&#xff1a;f(x)为目标函…

rom定制系列------红米k30_4G版澎湃os安卓13批量线刷固件

&#x1f49d;&#x1f49d;&#x1f49d;红米k30 4G版&#xff0c;机型代码;phoenix.此机型官方固件最后一版为稳定版13.0.6安卓12的固件。客户的软件需运行在至少安卓13的系统至少。测试原生适配有bug。最终测试在第三方澎湃os安卓13的固件可以完美运行。 &#x1f49d;&am…

Nginx 报错400 Request Header Or Cookie Too Large

错误的原因&#xff1a; 1、可能是你的网络DNS配置错误。 2、由request header过大所引起&#xff0c;request过大&#xff0c;通常是由于cookie中写入了较大的值所引起的。 3、访问太频繁&#xff0c;浏览器的缓存量太大&#xff0c;产生错误。 解决办法&#xff1a; 1、清…

钉钉平台开发小程序

一、下载小程序开发者工具 官网地址&#xff1a;小程序开发工具 - 钉钉开放平台 客户端类型 下载链接 MacOS x64 https://ur.alipay.com/volans-demo_MiniProgramStudio-x64.dmg MacOS arm64 https://ur.alipay.com/volans-demo_MiniProgramStudio-arm64.dmg Windows ht…

android——渐变色

1、xml的方式实现渐变色 效果图&#xff1a; xml的代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <shape xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools…

已知三角形三边长求面积用仓颉语言作答

仓颉语言 https://cangjie-lang.cn/ linux和win和mac均有sdk&#xff0c;在本机deepinlinuxv23下载到本地解压缩到目录下设置环境变量 source envsetup.sh 比java方便太多了&#xff0c;java每次都是要自己搞很久&#xff0c;当然&#xff0c;打开看一下envsertup.sh,和我们…

微信小程序生成二维码

目前是在开发小程序端 --> 微信小程序。然后接到需求&#xff1a;根据 form 表单填写内容生成二维码&#xff08;第一版&#xff1a;表单目前需要客户进行自己输入&#xff0c;然后点击生成按钮实时生成二维码&#xff0c;不需要向后端请求&#xff0c;不存如数据库&#xf…

rhce:web服务器

web服务器简介 服务器端&#xff1a;此处使用 nginx 提供 web 服务&#xff0c; RPM 包获取&#xff1a; http://nginx.org/packages/ /etc/nginx/ ├── conf.d #子配置文件目录 ├── default.d ├── fastcgi.conf ├── fastcgi.conf.default ├── fastcgi_params #用…

解决使用netstat查看端口显示FIN_WAIT的问题

解决使用netstat查看端口显示FIN_WAIT的问题 1. 理解`FIN_WAIT`状态2. 检查应用程序3. 检查网络延迟和稳定性4. 更新和修补系统5. 调整TCP参数6. 使用更详细的工具进行分析7. 咨询开发者或技术支持8. 定期监控和评估结论在使用 netstat查看网络连接状态时,如果发现大量连接处…

01LangChain 实战课开篇——AI奇点时刻

LangChain 实战课开篇——AI奇点时刻 课程简介 课程背景&#xff1a;随着ChatGPT和GPT-4的出现&#xff0c;AI技术与实际应用之间的距离变得前所未有的近。LangChain作为基于大模型的应用开发框架&#xff0c;为程序员提供了开发智能应用的新工具。 LangChain 概述 定义&am…

Flutter启动流程(2)

Flutter启动流程 简述 我们还是从Flutter在Android上启动流程来学习Flutter&#xff0c;只要学习了启动流程&#xff0c;就会对Flutter的实现有一些理解&#xff0c;否则像Flutter&#xff0c;RN这些对于原生应用开发者就像是一个黑盒子。 Flutter 在Android上必然还是要依赖…