数据库中 SQL Hint 是什么?

前言

最近在调研业界其他数据库中 SQL Hint 功能的设计和实现,整体上对 Oracle、Mysql、Postgresql、 Apache Calcite 中的 SQL Hint 的设计和功能都进行了解,这里整理一篇文章来对其进行梳理,一是帮助自己未来回顾,加深自己的思考,二是也能帮助大家更好的了解数据库 SQL Hint 的实现原理。

由于我是做数据库引擎开发的,所以每日一学系列,就先以数据库技术作作为开头,我估计我最少会写几十篇内容来介绍数据库技术吧,每天分享一个点,来帮助大家理解数据库的使用和原理,分享的内容我应该会逐渐由浅入深,好了,今天的主题开始。

一、什么是数据库 SQL Hint

SQL Hint 是一种能够让用户干预数据库 SQL 优化的方式,相当于给用户开了一个后门,当数据库本身对于某些 SQL 优化的不够好时,那么用户就可以结合自己的经验,尝试使用 Hint 来干预数据库的优化。

举个列子,比如能够让用户指定 SQL 查询 Join Order 的顺序、单个 Query 级别的 Session 参数等等。

虽然数据库 SQL 优化器在大部分场景已经能够产出较优的计划,但可能存在某些复杂场景,比如基数评估不准等,可能会导致最终的计划性能较低,此时用户就可以通过 SQL Hint 的方式,来干预优化器的计划产生,从而产出更优的计划。

数据库 SQL Hint 的一般有两种格式:以/*+开头的一种特殊的 SQL 注释(比如 Oracle、Mysql)和 SQL 关键字(比如 SQL Server),业界比较多的设计是前面这扬中,也就是 SQL 注释。

由于数据库 SQL Hint 是 SQL 注释,这不会破坏 SQL 标准和兼容性,在 Oracle、Mysql 中,SQL Hint 必须出现在 Select、Insert、Update 等 SQL 关键字后面。多个 Hint 之间可以是","进行分隔,也可以是空格分隔。

对于 SQL Hint 的作用域,一般可以划分为三种类型:

  1. 单个 Query 级别 -- 对于 Query 级别的 Hint,即 Hint 作用于是整个 Query 级别的,比如 Query 的 Session 参数,资源组的配置
  2. 一个 Query 中 的 Query Block 级别 -- Query Block 级别的 Hint,一般作用于所属的 Query Block,对于 Query Block 的解释,下面这张图比较清晰:

添加图片注释,不超过 140 字(可选)

  1. Table 级别 -- Table 级别的 Hint 作用于比较好理解,就是作用于 Table Scan 的,同时 Table 的Hint 只能 Attach 所属的 Table Scan 上。

下面是一个使用 SQL Hint 的 SQL:

ini 复制代码
SELECT 
/*+ HASH_JOIN(e, d),RESOURCE(mem='128mb', parallelism='24')*/ 
  e.last_name, 
  d.location_id 
FROM 
  employees e, 
  departments d 
WHERE 
  e.dep_id = d.dep_id;

/*+ HASH_JOIN(e, d),RESOURCE(mem='128mb', parallelism='24') */表示有两个 Hint,第一个表示employees和departments的 Join 实现方式使用 HashJoin。第二个 Hint 表示这个 Query 使用资源的配置,每个 Task 128 MB,并发度为 24.w。

SQL Hint 是一种能够让用户干预数据库 SQL 优化的方式,相当于给用户开了一个后门,当数据库本身对于某些 SQL 优化的不够好时,那么用户就可以结合自己的经验,尝试使用 Hint 来干预数据库的优化,相当于留了一个后门。

二、为什么需要数据库 SQL Hint

前面有说到,需要 SQL Hint 的核心原因,是希望为优化器提供一种人工可干预的优化手段。

对于客户侧存在某些特殊场景的一些问题,对于这种特殊 Case,优化器可能不能发挥比较好的优化,从而会导致查询时间很久,此时我们期望能够以很小的成本,能够手动干预和介入到优化中,来解决客户现场的问题。

对于用户而言,我们期望其尽可能少的感知到自己需要手工优化的点,尽可能多的让优化器来做这些优化以及产出一个较好的优化计划。

更多精彩内容,欢迎关注我的公粽号: 【雷克分析】关注私信发送:命令、提效、数据库、提示词、calcite、论文,有学习资料等着你欢迎关注

相关推荐
渣渣灰飞11 分钟前
MySQL 系统学习 第四阶段:MySQL 高级 第一节:索引(Index)
数据库·学习·mysql
山峰哥16 分钟前
数据库工程与SQL优化实战指南‌
数据库·sql·oracle·深度优先·宽度优先
Quincy_Freak1 小时前
Python 轻量化数据存储实践:国产化环境下SQLite高效管理方案
数据库·sqlite·数据库管理·大数据分析·sqlitego
SelectDB技术团队2 小时前
Agent 场景动态 JSON 性能拆解:Apache Doris 比 ClickHouse 快 7 倍、比 Elasticsearch 快 2 倍
数据库·clickhouse·elasticsearch·json·apache·日志分析·apache doris
greasyfork2 小时前
多种数据库管理混乱?Navicat Premium 17 for Mac 统一解决
数据库·mysql·macos·mac
Dream_fly_iboy2 小时前
系统架构设计师之数据库
数据库
风和先行3 小时前
Android 数据库相关学习总结
android·数据库·学习
宠友信息3 小时前
Spring Boot与异步审核构建仿小红书源码内容发布全流程
java·数据库·spring boot·redis·mysql·oracle·uni-app
2401_873479403 小时前
如何识别代理IP和伪装流量?用IP情报工具三步穿透住宅代理伪装
网络·数据库·网络协议·tcp/ip·ip
诚信定制8394 小时前
如何启动 Redis 服务:详细步骤指南
数据库·redis·缓存