暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【干货攻略】DM如何实现不更改SQL而改变其执行计划

达梦E学 2022-09-05
672

-----正文-----

SQL优化中,有时数据库选择的执行计划并不是最优的,这时会考虑使用HINT提示来改变SQL的执行计划(比如索引扫描修改为全表扫描、嵌套循环连接修改为哈希连接)。但使用HINT提示需要修改对应的SQL语句,增加HINT子句,在应用中不是很方便,此时可以使用SF_INJECT_HINT函数来绑定SQL语句使其使用对应的HINT。


本章内容已在如下环境中测试:

操作系统:银河麒麟V10

数据库:DM8

相关关键字:DM数据库、INJECT HINT、HINT提示


一、HINT提示

如下SQL,默认两表关联使用的是哈希连接HASH JOIN

    explain select a.department_id, a.employee_name, b.department_name
    from dmhr.employee a, dmhr.department b
    where a.department_id = b.department_id;

    使用hint改变其执行计划,修改SQL增加HINT提示 /*+use_nl(a,b) */使其使用内嵌套循环连接:

      explain select /*+use_nl(a,b) */ a.department_id, a.employee_name, b.department_name
      from dmhr.employee a, dmhr.department b
      where a.department_id = b.department_id;


      二、INJECT HINT函数

      HINT提示需要修改SQL语句, SF_INJECT_HINT函数提供无需修改 SQL 语句依然能按照指定的 HINT 运行语句的相关功能。支持SQL精确匹配和模糊匹配。

      使用时的限制条件如下:

      (1)INI参数ENABLE_INJECT_HINT需设置为1;

      (2)SQL只能是语法正确的增删改查语句;

      (3)SQL会经过系统格式化,格式化之后的SQL和指定的规则名称必须全局唯一;

      (4)HINT一指定,则全局生效;

      (5)系统检查SQL匹配时,必须是整条语句完全匹配,不能是语句中子查询匹配;

      (6)可通过 SYSINJECTHINT 视图查看已指定的 SQL 语句和对应的 HINT。


      2.1 使用前提

      使用SF_INJECT_HINT函数需设置INI 参数 ENABLE_INJECT_HINT为1;

        select * from v$dm_ini t where para_name = 'ENABLE_INJECT_HINT';
        alter system set 'ENABLE_INJECT_HINT'=1 both;


        2.2 INJECT HINT函数使用示例(精确匹配)

        使用SF_INJECT_HINT函数指定SQL HINT,默认是精确匹配SQL:

          sf_inject_hint(
          sql_text => 'select a.department_id, a.employee_name, b.department_name from dmhr.employee a, dmhr.department b where a.department_id = b.department_id;',
          hint_text =>'use_nl(a,b)',
          name =>'TESTSQL',
          description => 'this is a test hint',
          validate => true);

          这里指定SQL语句的两表关联使用nest loop join,指定后查看该sql的执行计划,可以看到执行计划显示nest loop join

            explain select a.department_id, a.employee_name, b.department_name from dmhr.employee a, dmhr.department b where a.department_id = b.department_id;


            2.3 INJECT HINT函数使用示例(模糊匹配)

            SF_INJECT_HINT函数精确匹配要求SQL必须严格一致。有的业务SQL较长,查询字段不同、语句中间有空格等,这时精确匹配的规则会使指定HINT无法生效。此时可以使用SF_INJECT_HINT函数的fuzzy 参数使其支持SQL模糊匹配。

            例如,指定如下SQL的模糊匹配:

              sf_inject_hint(
              sql_text => 'from dmhr.employee a, dmhr.department b where a.department_id=b.department_id',
              hint_text =>'use_nl(a,b)',
              name =>'TESTJOIN',
              description => 'this is a test join hint.',
              validate => true,
              fuzzy = true
              );

              查看SQL执行计划,比如查询两张表所有列信息,可以看到两表使用nest loop join。

                explain select a.*, b.* from dmhr.employee a, dmhr.department b where a.department_id=b.department_id;

                HINT提示支持设置INI参数,比如设置ENABLE_HASH_JOIN参数为0,也可以实现相同的功能:

                  sf_inject_hint(
                  sql_text => 'from dmhr.employee a, dmhr.department b where a.department_id=b.department_id',
                  hint_text =>'ENABLE_HASH_JOIN(0)',
                  name =>'TEST_DISABLE_HASHJOIN',
                  description => 'this is a test join hint.',
                  validate => true,
                  fuzzy = true
                  );


                  2.4 INJECT HINT设置查看

                  查询SYSINJECTHINT视图可以查看已指定的 SQL 语句和对应的 HINT:

                    select NAME, DESCRIPTION, VALIDATE, SQL_TEXT, HINT_TEXT, CREATOR, CRTDATE from SYSINJECTHINT;


                    2.5 INJECT HINT状态修改

                    使用SF_ALTER_HINT函数可以设置INJECT HINT无效,置为无效后,相关的sql hint将不再生效。

                      SF_ALTER_HINT('TESTJOIN' ,'STATUS', 'DISABLED');

                      2.6 INJECT HINT设置删除

                      SF_DEINJECT_HINT函数可以将设置INJECT hint删除。

                        sf_deinject_hint('TESTJOIN');

                        三、说明

                        • HINT提示只能对单个sql修改设置HINT,SF_INJECT_HINT支持SQL模糊配置设置,两者都是针对SQL语句生效。

                        • SQL语句模糊匹配时,执行的SQL语句必须与SF_INJECT_HINT规则中的SQL语句完全相同(包括SQL语句中的空格等)。指定的HINT对所有符合SQL语句均生效。

                        • 两种方法不仅可以设置SQL多表连接方法,索引提示,也可以设置INI参数提示(支持使用HINT的INI参数可通过V$HINT_INI_INFO 动态视图查询)、统计信息提示等,使SQL优化更灵活。


                        >>> THE END <<<

                        好,以上是本期干货分享内容,希望能给大家带来帮助。



                         
                         


                        相关推荐

                        干货 | 达梦数据库异地备份的方式和策略
                        干货 | 浅谈达梦SQL调优——执行计划和ET
                        干货 | 达梦数据库关键字屏蔽
                        干货 | 达梦数据库如何获取SQL实际执行计划
                        开班 | 达梦DM8-DCA在线认证培训开班通知
                        内容丨青城

                        文章转载自达梦E学,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                        评论