数据库中 SQL Hint 是什么?

本文探讨了SQLHint的功能、使用场景,它是用户干预数据库SQL优化的一种方式,特别在优化器处理复杂场景时提供人工优化手段。作者还介绍了不同数据库中SQLHint的格式和作用范围,以及为何需要SQLHint以解决特定场景下的性能问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

最近在调研业界其他数据库中 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:


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、论文,有学习资料等着你 ,欢迎关注

在面对复杂的SQL查询时,优化器的选择可能并不总是最优的,尤其是在统计信息不准确或缺失的情况下。HINT功能在这种时候就显得尤为重要,它允许用户通过在SQL语句中添加特定的提示来引导优化器,从而生成更加高效的执行计划。在达梦数据库中,HINT的使用非常灵活和强大,可以通过指定索引使用、连接操作方式以及连接顺序等方式来直接干预查询的执行计划。 参考资源链接:[DM数据库优化:HINT功能详解与应用](https://wenku.youkuaiyun.com/doc/4xqtm57o6a?spm=1055.2569.3001.10343) 具体来说,如果你知道某些表经常进行范围查询,你可以使用INDEX HINT来强制优化器使用特定的索引,减少扫描的数据量。同样地,如果你发现优化器选择了嵌套循环连接(NL)而你认为应该使用哈希连接(Hash),可以在查询中显式地添加USE_HASH或NO_USE_NL HINT来强制优化器改变策略。 例如,假设有一个表t1和表t2需要进行连接操作,你可以通过添加USE_HASH HINT来指导优化器使用哈希连接来提高连接效率: ```sql SELECT /*+ USE_HASH(t1) */ * FROM t1, t2 WHERE t1.id = t2.fk_t1_id; ``` 在这个例子中,/*+ USE_HASH(t1) */就是一个HINT,它告诉优化器对t1表使用哈希连接。这在表t1不适合使用索引或者连接操作中需要扫描较多数据的情况下尤其有用。 如果你在优化过程中需要参考HINT功能的更多细节和高级应用,建议深入阅读《DM数据库优化:HINT功能详解与应用》。该资料不仅详细介绍了HINT的语法和使用方法,还包括了各种类型的HINT以及它们如何影响查询执行计划的详细说明。通过这份资源,你可以更全面地掌握HINT的使用技巧,进而提升数据库性能和管理效率。 参考资源链接:[DM数据库优化:HINT功能详解与应用](https://wenku.youkuaiyun.com/doc/4xqtm57o6a?spm=1055.2569.3001.10343)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值