精华内容
下载资源
问答
  • Hint

    2021-01-02 09:55:23
    <div><p>O Hint do EditText que usa o MaskedEditText não funciona.</p><p>该提问来源于开源项目:toshikurauchi/MaskedEditText</p></div>
  • hint

    2016-05-18 15:24:47
    左连接:hint不生效:(+) 生效了。 ...

    左连接:hint不生效:(+) 生效了。

    来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8568259/viewspace-2102417/,如需转载,请注明出处,否则将追究法律责任。

    转载于:http://blog.itpub.net/8568259/viewspace-2102417/

    展开全文
  • <ul><li><strong><code>hint</code> version:</strong> 3.4.10</li><li><strong><code>Node.js</code> version:</strong> 10.12.0</li><li><strong><code>npm</code> version:</strong> 6.4.1</li></ul> <h2><code>...
  • hint in the middle is blank (as intended), so you click Hint the second time (after getting the "relationship" hint) and get no response. You need to click a third time to get the "fits&#...
  • Hint Inconsistencies

    2020-12-08 20:33:05
    which looks like a mistake</li><li>The hint "is in a sages closet" should have an apostrophe: sage's... I think. =)</li></ul> <p>Thanks for all the hard work! 👍 </p><p>该提问...
  • Sound hint

    2020-12-02 10:09:52
    <div><p>Any chance for implementing sound hint ? <p>For example <code>notify-send "Sound test" --hint=string:sound-file:/path/to/sound.wav</code></p> <p>this works in most notification ...
  • Disable hint

    2020-12-26 09:54:31
    <div><p>Allow users to hide the hint when using autoselect. Closes #120. <p>With hint: <p><img width="711" alt="screen shot 2017-07-07 at 14 41 06 1" src=...
  • Balloon Hint

    2015-02-05 21:37:14
    delphi 2010的Balloon Hint改到2007
  • js hint 提示js hint 提示js hint 提示js hint 提示js hint 提示js hint 提示js hint 提示js hint 提示js hint 提示js hint 提示js hint 提示js hint 提示
  • <p>So, based on the above, the decision is create a much simpler hint that warns/informs you if you do configure IE as a target browser <em>and</em> you use flexbox. The warning could be along the ...
  • <div><p>该提问来源于开源项目:angular/angular-hint</p></div>
  • Merge with hint

    2020-12-29 07:30:25
    when route with hint, there are two sql statement: one is hint sql, the other is real sql. first, get the route from hint sql, and save it into current session instance. second, get the route from ...
  • Hint UI Customization

    2020-12-31 05:34:02
    - Add customization settings for the hint dialog - Add ACRE2 UI settings to addon options - Add color settings for each type of hint message - Add font settings for hint dialog - Change hint display ...
  • simplify hint params

    2021-01-10 16:39:31
    s hint is currently send as: loc=55.69384,12.50107&hint=HUUHAOkFAAAnAAAAnwAAABZVt1nTxMk_avtUADgTEwB <p>this could be simplified to: loc=55.69384,12.50107,HUUHAOkFAAAnAAAAnwAAABZVt1...
  • Spark Hint

    2019-11-28 10:55:11
    SparkHint是在使用SparkSQL开发过程中,针对SQL进行优化的一点小技巧,我们可以通过Hint的方式实现BraodcastJoin优化、Reparttion分区等操作,提供了传统SQL中无法实现的一些功能。 语法介绍 SparkSQL的语法定义是通...

    介绍

    SparkHint是在使用SparkSQL开发过程中,针对SQL进行优化的一点小技巧,我们可以通过Hint的方式实现BraodcastJoin优化、Reparttion分区等操作,提供了传统SQL中无法实现的一些功能。

    语法介绍

    SparkSQL的语法定义是通Antlr4实现的,Antlr4是一个提供语法定义、语法解析等第三方库,Antlr4语法的定义基本复合正则表达式,因此会正则表达式的同学可以尝试去理解一下下面这段代码。

    # 来自于Spark源代码的SqlBase.g4文件
    # 内容有部分删除,如查看源代码是请注意
    
    # 定义特别查询的语法树节点
    querySpecification
        : ((kind=SELECT (hints+=hint)* setQuantifier? namedExpressionSeq fromClause?
           | fromClause (kind=SELECT setQuantifier? namedExpressionSeq)?)
           lateralView*
           (WHERE where=booleanExpression)?
           aggregation?
           (HAVING having=booleanExpression)?
           windows?)
        ;
    
    # Hint基本的格式,开始符号、结束符号,语句列表格式,格式为
    # /*+ 多条语句 */
    hint
        : '/*+' hintStatements+=hintStatement (','? hintStatements+=hintStatement)* '*/'
        ;
    # 单个Hint的组成
    # 名称
    # 名称(参数, 参数2...)
    hintStatement
        : hintName=identifier
        | hintName=identifier '(' parameters+=primaryExpression (',' parameters+=primaryExpression)* ')'
        ;
    

    上述Hint的语法树中定义了Hint的使用方式为:

    • SparkHint只能在Select语句中使用
    • SparkHint的结果必须要SELECT关键字以后标识,且结构体为
      /*+ … */

    目前SparkHint支持的语法很少,只有两种语法:

    • Broadcast: MAPJOIN/BROADCASTJOIN/BROADCAST
    • Coalesce: REPARTITION/COALESCE

    下面的例子简单介绍一下SparkHint是如何使用的:

        select /*+ BRAODCASTJOIN(B) */
            A.COL1
            , B.COL2
        FROM 
            A LEFT JOIN B USING(COL3); 
    
    

    源代码解析

    SparkSQL的解析过程大致上可以分为一下几个过程:

    • G4文件定义语法
    • AstBuilder/SparkAstBuilder将语法树种的信息解析成相应的逻辑计划
    • Analyzer层将一些LogicalPlan翻译成另一个LogicalPlan语法
    • Optimizer层在Schema等级别进行优化,生成LogicalPlan
    • SparkPlan将LogicPlan翻译成影响的SparkPlan
    • 执行SparkPlan映射成底层的RDD操作

    这里简单介绍一下SparkSQL的解析过程,后续我们再写一篇文章详细介绍SparkSQL解析的整体过程。

    G4文件

    当我们使用 sparkSession.sql(string) 执行SparkHint语句时,首先要经历语法解析,在这里会将SparkHint的语法解析成相应的hintStatement语法,并且将HintStatement中的参数进行提取。

    # Hint基本的格式,开始符号、结束符号,语句列表格式
    hint
        : '/*+' hintStatements+=hintStatement (','? hintStatements+=hintStatement)* '*/'
        ;
    
    # 单个Hint的组成
    # 名称
    # 名称(参数, 参数2...)
    hintStatement
        : hintName=identifier
        | hintName=identifier '(' parameters+=primaryExpression (',' parameters+=primaryExpression)* ')'
    

    AstBuilder解析

    SparkSQL采用的是Antlr4的Visitor模式,继承Visitor接口实现相应的代码(AstBuilder.java和 SparkAstBuilder.java),这两个类的主要作用是将一条SQL语句的每一部分翻译成相应的逻辑计划(LogicalPlan)代码。然后SparkSQL的三层将生成的LogicalPlan进行相应的解析、优化和转化成底层的RDD操作。

      /**
       * Add [[UnresolvedHint]]s to a logical plan.
       */
      private def withHints(
          ctx: HintContext,
          query: LogicalPlan): LogicalPlan = withOrigin(ctx) {
        var plan = query
        // 将hintStatement列表转换成UnresolvedHint对象
        ctx.hintStatements.asScala.reverse.foreach { case stmt =>
          plan = UnresolvedHint(stmt.hintName.getText, stmt.parameters.asScala.map(expression), plan)
        }
        plan
      }
    

    这段代码结合G4文件的语法就能得到一下几点:

    • 一个hintStatemenet转换成一个UnresolvedHint
    • 生成UnresolvedHint对象时,将定义的hintName以及params进行了存储

    Analyzer

    Analyzer对象可以理解成是一系列解析过程的集合,每一个解析过程会针对一种LogicalPlan进行解析,并生成后续可以被优化以及翻译的过程LogicalPlan。

    Analyzer的解析过程列表,Hint的解析过程排列在第一个:

    # Spark 2.4 版本代码
    lazy val batches: Seq[Batch] = Seq(
        Batch("Hints", fixedPoint,
          new ResolveHints.ResolveBroadcastHints(conf),
          ResolveHints.ResolveCoalesceHints,
          ResolveHints.RemoveAllHints),
        Batch("Simple Sanity Check", Once,
          LookupFunctions),
        Batch("Substitution", fixedPoint,
          CTESubstitution,
          WindowsSubstitution,
          EliminateUnions,
          new SubstituteUnresolvedOrdinals(conf)),
        Batch("Resolution", fixedPoint,
          ResolveTableValuedFunctions ::
          ResolveRelations ::
          ResolveReferences ::
          ResolveCreateNamedStruct ::
          ResolveDeserializer ::
          ResolveNewInstance ::
          ResolveUpCast ::
          ResolveGroupingAnalytics ::
          ResolvePivot ::
          ResolveOrdinalInOrderByAndGroupBy ::
          ResolveAggAliasInGroupBy ::
          ResolveMissingReferences ::
          ExtractGenerator ::
          ResolveGenerate ::
          ResolveFunctions ::
          ResolveAliases ::
          ResolveSubquery ::
          ResolveSubqueryColumnAliases ::
          ResolveWindowOrder ::
          ResolveWindowFrame ::
          ResolveNaturalAndUsingJoin ::
          ResolveOutputRelation ::
          ExtractWindowExpressions ::
          GlobalAggregates ::
          ResolveAggregateFunctions ::
          TimeWindowing ::
          ResolveInlineTables(conf) ::
          ResolveHigherOrderFunctions(catalog) ::
          ResolveLambdaVariables(conf) ::
          ResolveTimeZone(conf) ::
          ResolveRandomSeed ::
          TypeCoercion.typeCoercionRules(conf) ++
          extendedResolutionRules : _*),
        Batch("Post-Hoc Resolution", Once, postHocResolutionRules: _*),
        Batch("Nondeterministic", Once,
          PullOutNondeterministic),
        Batch("UDF", Once,
          HandleNullInputsForUDF),
        Batch("FixNullability", Once,
          FixNullability),
        Batch("Subquery", Once,
          UpdateOuterReferences),
        Batch("Cleanup", fixedPoint,
          CleanupAliases)
      )
    

    我们可以看到Hint的Batch里头有三个对象,一个是ResolveBroadcastHints,一个是ResolveCoalesceHints,最后一个是RemoveAllHints,我们来看一下源代码:

    • ResolveCoalesceHints
    /**
       * COALESCE Hint accepts name "COALESCE" and "REPARTITION".
       * Its parameter includes a partition number.
       */
      object ResolveCoalesceHints extends Rule[LogicalPlan] {
        private val COALESCE_HINT_NAMES = Set("COALESCE", "REPARTITION")
        
        def apply(plan: LogicalPlan): LogicalPlan = plan.resolveOperators {
          // 判断为UnresolvedHint对象并且hintName为REPARTITION/COALESCE
          case h: UnresolvedHint if COALESCE_HINT_NAMES.contains(h.name.toUpperCase(Locale.ROOT)) =>
            // 获取的HintName
            val hintName = h.name.toUpperCase(Locale.ROOT)
            // 是否shuffle
            val shuffle = hintName match {
              case "REPARTITION" => true
              case "COALESCE" => false
            }
            // 分区数量
            val numPartitions = h.parameters match {
              case Seq(IntegerLiteral(numPartitions)) =>
                numPartitions
              case Seq(numPartitions: Int) =>
                numPartitions
              case _ =>
                throw new AnalysisException(s"$hintName Hint expects a partition number as parameter")
            }
            
            // 生成Repartition LogicalPlan对象
            Repartition(numPartitions, shuffle, h.child)
        }
      }
    
    /**
       * Removes all the hints, used to remove invalid hints provided by the user.
       * This must be executed after all the other hint rules are executed.
       */
      object RemoveAllHints extends Rule[LogicalPlan] {
        def apply(plan: LogicalPlan): LogicalPlan = plan resolveOperatorsUp     {
          // 直接将Dataset链进行返回,不生成任何LogicalPlan,因此为空操作
          case h: UnresolvedHint => h.child
        }
      }
    
    /**
       * For broadcast hint, we accept "BROADCAST", "BROADCASTJOIN", and "MAPJOIN", and a sequence of
       * relation aliases can be specified in the hint. A broadcast hint plan node will be inserted
       * on top of any relation (that is not aliased differently), subquery, or common table expression
       * that match the specified name.
       *
       * The hint resolution works by recursively traversing down the query plan to find a relation or
       * subquery that matches one of the specified broadcast aliases. The traversal does not go past
       * beyond any existing broadcast hints, subquery aliases.
       *
       * This rule must happen before common table expressions.
       */
      class ResolveBroadcastHints(conf: SQLConf) extends Rule[LogicalPlan] {
        private val BROADCAST_HINT_NAMES = Set("BROADCAST", "BROADCASTJOIN", "MAPJOIN")
    
        def resolver: Resolver = conf.resolver
    
        private def applyBroadcastHint(plan: LogicalPlan, toBroadcast: Set[String]): LogicalPlan = {
          // Whether to continue recursing down the tree
          var recurse = true
    
          val newNode = CurrentOrigin.withOrigin(plan.origin) {
            plan match {
              // 将子Dataset进行BroadCast操作
              case u: UnresolvedRelation if toBroadcast.exists(resolver(_, u.tableIdentifier.table)) =>
                ResolvedHint(plan, HintInfo(broadcast = true))
              case r: SubqueryAlias if toBroadcast.exists(resolver(_, r.alias)) =>
                ResolvedHint(plan, HintInfo(broadcast = true))
    
              case _: ResolvedHint | _: View | _: With | _: SubqueryAlias =>
                // Don't traverse down these nodes.
                // For an existing broadcast hint, there is no point going down (if we do, we either
                // won't change the structure, or will introduce another broadcast hint that is useless.
                // The rest (view, with, subquery) indicates different scopes that we shouldn't traverse
                // down. Note that technically when this rule is executed, we haven't completed view
                // resolution yet and as a result the view part should be deadcode. I'm leaving it here
                // to be more future proof in case we change the view we do view resolution.
                recurse = false
                plan
    
              case _ =>
                plan
            }
          }
    
          if ((plan fastEquals newNode) && recurse) {
            newNode.mapChildren(child => applyBroadcastHint(child, toBroadcast))
          } else {
            newNode
          }
        }
    
        def apply(plan: LogicalPlan): LogicalPlan = plan resolveOperatorsUp {
          // 判断是否为BroadCastJoin操作
          case h: UnresolvedHint if BROADCAST_HINT_NAMES.contains(h.name.toUpperCase(Locale.ROOT)) =>
            // 如果参数为空,则将子Dataset进行broadcast
            if (h.parameters.isEmpty) {
              // If there is no table alias specified, turn the entire subtree into a BroadcastHint.
              ResolvedHint(h.child, HintInfo(broadcast = true))
            } else {
              // Otherwise, find within the subtree query plans that should be broadcasted.
              // 如果参数不为空时,则对表名的Dataset进行BroadCastJoin操作
              applyBroadcastHint(h.child, h.parameters.map {
                case tableName: String => tableName
                case tableId: UnresolvedAttribute => tableId.name
                case unsupported => throw new AnalysisException("Broadcast hint parameter should be " +
                  s"an identifier or string but was $unsupported (${unsupported.getClass}")
              }.toSet)
            }
        }
      }
    

    所以到这里SparkHint框架基本就结束了,因为SparkHint操作生成的是Unresolved级别的LogicalPlan对象,因此会在Analyzer层被相应的Batch捕捉并处理成别的LogicalPlan对象。

    总结

    SparkHint目前仅提供了BroadCastJoin和REPARTITION两种操作,其他的Hint语法都会被删除忽而略;我们可以在SQL中使用者两种语法来达到优化的目的。如果有什么写的不对的地方,请大家指点出来~

    展开全文
  • hint详解

    万次阅读 2017-06-22 14:43:35
    一、提示(Hint)概述 1 为什么引入Hint? Hint是Oracle数据库中很有特色的一个功能,是很多DBA优化中经常采用的一个手段。那为什么Oracle会考虑引入优化器呢?基于代价的优化器是很聪明的,在绝大多数情况...

    一、提示(Hint)概述

    1

    为什么引入Hint?

    Hint是Oracle数据库中很有特色的一个功能,是很多DBA优化中经常采用的一个手段。那为什么Oracle会考虑引入优化器呢?基于代价的优化器是很聪明的,在绝大多数情况下它会选择正确的优化器,减轻DBA的负担。

    但有时它也聪明反被聪明误,选择了很差的执行计划,使某个语句的执行变得奇慢无比。此时就需要DBA进行人为的干预,告诉优化器使用指定的存取路径或连接类型生成执行计划,从而使语句高效地运行。Hint就是Oracle提供的一种机制,用来告诉优化器按照告诉它的方式生成执行计划。

    2

    不要过分依赖Hint

    当遇到SQL执行计划不好的情况,应优先考虑统计信息等问题,而不是直接加Hint了事。如果统计信息无误,应该考虑物理结构是否合理,即没有合适的索引。只有在最后仍然不能SQL按优化的执行计划执行时,才考虑Hint。

    毕竟使用Hint,需要应用系统修改代码,Hint只能解决一条SQL的问题,并且由于数据分布的变化或其他原因(如索引更名)等,会导致SQL再次出现性能问题。

    3

    Hint的弊端

    • Hint是比较"暴力"的一种解决方式,不是很优雅。需要开发人员手工修改代码。

    • Hint不会去适应新的变化。比如数据结构、数据规模发生了重大变化,但使用Hint的语句是感知变化并产生更优的执行计划。

    • Hint随着数据库版本的变化,可能会有一些差异、甚至废弃的情况。此时,语句本身是无感知的,必须人工测试并修正。

    4

    Hint与注释关系

    提示是Oracle为了不破坏和其他数据库引擎之间对SQL语句的兼容性而提供的一种扩展功能。Oracle决定把提示作为一种特殊的注释来添加。它的特殊性表现在提示必须紧跟着DELETE、INSERT、UPDATE或MERGE关键字。

    换句话说,提示不能像普通注释那样在SQL语句中随处添加。且在注释分隔符之后的第一个字符必须是加号。在后面的用法部分,会详细说明。

    5

    Hint功能

    Hint提供的功能非常丰富,可以很灵活地调整语句的执行过程。通过Hint,我们可以调整:

    • 优化器类型

    • 优化器优化目标

    • 数据读取方式(访问路径)

    • 查询转换类型

    • 表间关联的顺序

    • 表间关联的类型

    • 并行特性

    • 其他特性

    二、Hint用法

    1

    语法

    1)关键字说明

    • DELETE、INSERT、SELECT和UPDATE是标识一个语句块开始的关键字,包含提示的注释只能出现在这些关键字的后面,否则提示无效。

    • "+"号表示该注释是一个提示,该加号必须立即跟在"/*"的后面,中间不能有空格。

    • hint是下面介绍的具体提示之一,如果包含多个提示,则每个提示之间需要用一个或多个空格隔开。

    • text是其它说明hint的注释性文本

    2)提示中的错误

    提示中的语法错误不会报错,如果解析器不能解析它,就会把它看做一个普通注释处理。这也是容易造成困惑的一点,使用的Hint到底是否起效?可以采用一些手段,检查提示的有效性。需要注意的是,那些语法正确但引用对象错误的提示是不会被报告的。

    • explain plan + dbms_xplan

    使用dbms_xplan输出中的note选项。

    • 10132事件

    在10g中,这个事件产生的输出文档的末尾有一部分内容专门讲提示。通过它可以检查两个方面:一是每个用到的提示都会被列出来。如果漏掉了哪个,就说明这个提示没有被识别;二是检查是否有一些信息指明了出现提示错误(如果出错,err值将大于0)。

    3)提示中的对象

    SELECT /*+ INDEX(table_name index_name) */ ...

    • table_name是必须要写的,且如果在查询中使用了表的别名,在hint也要用表的别名来代替表名。

    • index_name可以不必写,Oracle会根据统计值选一个索引。

    • 如果索引名或表名写错了,那这个hint就会被忽略。

    • 如果指定对象是视图,需要按此方法指定。/*+hint view.table ...*/,其中table是view中的表。

    • 一个很常见的错误时,在使用提示的时候最易犯的错误是与表的别名有关。正确的规则是,当在提示中使用表时,只要表有别名就应该使用别名而不是表名。

    2

    提示的作用域

    • 查询块

    初始化参数提示对整个SQL语句起作用,其他的提示仅仅对查询块起作用。仅仅对单个查询块起作用的提示,必须在它控制的查询块内指定。

    SQL优化:一篇文章说清楚Oracle Hint的正确使用姿势

    • 例外 - 全局提示

    可以使用点号引用包含在其他查询块(假设这些块已命名)中的对象。全局提示的语法可以支持两层以上的引用,对象间必须用点号分隔。

    SQL优化:一篇文章说清楚Oracle Hint的正确使用姿势

    • 命名查询块

    既然where子句中的子查询是没有命名的,它们的对象就不能被全局提示引用。为了解决这个问题,10g中使用了另一种方法来解决-命名查询块。查询优化器可以给每个查询生成一个查询块名,而且还可以使用提示qb_name手工为每个查询块命名。大多数提示都可以通过参数来指定在那个查询块中有效。

    SQL优化:一篇文章说清楚Oracle Hint的正确使用姿势

    *在提示中通过@来引用一个查询块。

    3

    提示数据字典

    Oracle在11g的版本中提供了一个数据字典—V$SQL_HINT。通过这个数据字典可以看到提示的出现版本、概要数据版本、SQL特性以及相反提示等。

    SQL优化:一篇文章说清楚Oracle Hint的正确使用姿势

    • INVERSE

    这个hint相反操作的hint。

    • VERSION

    代表着这个hint正式公布引入的版本。

    三、Hint分类

    1

    和优化器相关的

    当对优化器为某个语句所制定的基本执行计划不满意时,最好的办法就是通过提示来转换优化器的模式,并观察其转换后的结果,看是否已经达到期望程度。如果只通过转换优化器的模式就可以获得非常好的执行计划,则就没有必要额外使用更为复杂的提示了。

    • OPT_PARAM

    这个提示的作用就是使我们在某条语句中指定某个系统参数值。

    • ALL_ROWS

    为实现查询语句整体最优化而引导优化器制定最少成本的执行计划。这个提示会使优化器选择一条可最快检索所有查询行的路径,而代价就是在检索一行数据时,速度很慢。

    • FIRST_ROWS

    为获得最佳响应时间而引导优化器制定最少成本的执行计划。这个提示会使优化器选择可最快检索出查询的第一行(或指定行)数据的路径,而代价就是检索很多行时速度就会很慢。利用FIRST_ROWS来优化的行数,默认值为1,这个值介于10到1000之间,这个使用FIRST_ROWS(n)的新方法是完全基于代价的方法。它对n很敏感,如果n值很小,CBO就会生成包含嵌套循环以及索引查找的计划;如果n很大,CBO会生成由哈希连接和全表扫描组成的计划(类似ALL_ROWS)。

    • CHOOSE

    依据SQL中所使用到的表的统计信息存在与否,来决定使用RBO还是CBO。在CHOOSE模式下,如果能够参考表的统计信息,则将按照ALL_ROWS方式执行。除非在查询中的所有表都没有经过分析,否则choose提示会对整个查询使用基于代价的优化。如果在多表连接中有一个表经过分析过,那么就会对整个查询进行基于代价的优化。

    • RULE

    使用基于规则的优化器来实现最优化执行,即引导优化器根据优先顺序规则来决定查询条件中所使用到的索引或运算符的执行顺序来制定执行计划。这个提示强制oracle优先使用预定义的一组规则,而不是对数据进行统计;同时该提示还会使这个语句避免使用其他提示,除了DRIVING_SITE和ORDERED(不管是否进行基于规则的优化,这两个提示都可使用)。

    2

    和访问路径相关的

    • FULL

    告诉优化器通过全表扫描方式访问数据。这个提示只对所指定的表进行全表扫描,而不是查询中的所有表。FULL提示可以改善性能。这主要是因为它改变了查询中的驱动表,而不是因为全表扫描。在使用其他某些提示时,也必须使用FULL提示。只有访问整个表时,才可利用CACHE提示将表进行缓存。并行组中的某些提示也必须使用全表扫描。

    • CLUSTER

    引导优化器通过扫描聚簇索引来从索引表中读取数据。

    • HASH

    引导优化器按照哈希扫描的方式从表中读取数据。

    • INDEX

    告诉优化器对指定表通过索引的方式访问数据。当访问数据会导致结果集不完整时,优化器将忽略这个Hint。

    • NO_INDEX

    告诉优化器对指定表不允许使用索引。这个提示会禁止优化器使用指定索引。可以在删除不必要的索引之前在许多查询中禁止索引。如果使用了NO_INDEX,但是没有指定任何索引,则会执行全表扫描。如果对某个索引同时使用了NO_INDEX和会之产生冲突的提示(如INDEX),这时两个提示都会被忽略掉。

    • INDEX_ASC

    利用索引从表中读取数据时,引导优化器对提示中所指定索引的索引列值按照升序使用范围扫描。

    • INDEX_COMBINE

    告诉优化器强制选择位图索引。这个提示会使优化器合并表上的多个位图索引,而不是选择其中最好的索引(这是INDEX提示的用途)。还可以使用index_combine指定单个索引(对于指定位图索引,该提示优先于INDEX提示)。对于B树索引,可以使用AND_EQUAL提示而不是这个提示。

    • INDEX_JOIN

    索引关联,当谓词中引用的列上都有索引的时候,可以通过索引关联的方式来访问数据。这个提示可以将同一个表的各个不同索引进行合并,这样就只需要访问这些索引就可以了,节省了回表查询的时间。但只能在基于代价的优化器中使用该提示。这个提示不仅允许只访问表上的索引,这样可以扫描更少的代码块,并且它比使用索引并通过rowid扫描整个表快5倍。

    • INDEX_DESC

    利用索引从表中读取数据时,引导优化器对提示中所指定索引的索引列值按照降序使用范围扫描。

    • INDEX_FFS

    告诉优化器以INDEX FFS(index fast full scan)的方式访问数据。INDEX_FFS提示会执行一次索引的快速全局扫描。这个提示只访问索引,而不是对应的表。只有查询需要检索的信息都在索引上时,才使用这个提示。特别在表有很多列时,使用该提示可以极大地改善性能。

    • INDEX_SS

    强制使用index skip scan的方式访问索引。当在一个联合索引中,某些谓词条件并不在联合索引的第一列时(或者谓词并不在联合索引的第一列时),可以通过index skip scan来访问索引获得数据。当联合索引第一列的唯一值很少时,使用这种方式比全表扫描的方式效率要高。

    3

    和查询转换相关的

    • USE_CONCAT

    将含有多个OR或者IN运算符所连接起来的查询语句分解为多个单一查询语句,并为每个单一查询语句选择最优化查询路径,然后再将这些最优化查询路径结合在一起,以实现整体查询语句的最优化目的。只有在驱动查询条件中包含OR的时候,才可以使用该提示。

    • NO_EXPAND

    引导优化器不要为使用OR运算符号(或IN运算符)的条件制定相互结合的执行计划。正好和USE_CONCAT相反。

    • REWRITE

    当表连接的对象是数据量比较大的表或者需要获得使用统计函数处理过的结果时,为了提高执行速度可预先创建物化视图。当用户要求查询某个查询语句时,优化器会在从表中和从物化视图中读取数据的两种方法中选择一个更有效的方法来读取数据。该执行方法称之为查询重写。使用REWRITE提示引导优化器按照该方式执行。

    • MERGE

    为了能以最优方式从视图或者嵌套视图中读取数据,通过变换查询语句来直接读取视图使用的基表数据,该过程被称之为视图合并。不同的情况其具体使用类型也有所不同。该提示主要在视图未发生合并时被使用。尤其是对比较复杂的视图或者嵌套视图(比如使用了GROUP BY或DISTINC的视图)使用该提示,有时会取得非常好的效果。

    • UNNEST

    提示优化器将子查询转换为连接的方式。也就是引导优化器合并子查询和主查询并且将其向连接类型转换。

    • NO_UNNEST

    引导优化器让子查询能够独立地执行完毕之后再跟外围的查询做FILTER。

    • PUSH_PRED

    使用该提示可以将视图或嵌套视图以外的查询条件推入到视图之内。

    • NO_PUSH_PRED

    使用该提示确保视图或嵌套视图以外的查询条件不被推入到视图内部。

    • PUSH_SUBQ

    使用该提示引导优化器为不能合并的子查询制定执行计划。不能合并的子查询被优先执行之后,该子查询的执行结果将扮演缩减主查询数据查询范围的提供者角色。通常在无法执行子查询合并的情况下,子查询扮演的都是检验者角色,所以子查询一般被放在最后执行。在无法被合并的子查询拥有较少的结果行,或者该子查询可以缩减主查询查询范围的情况下,可以使用该提示引导优化器最大程度地将该子查询放在前面执行,以提高执行速度。但如果子查询执行的是远程表或者排序合并连接的一部分连接结果,则该提示将不起任何作用。

    • NO_PUSH_SUBQ

    使用该提示将引导优化器将不能实现合并的子查询放在最后执行。在子查询无法缩减主查询的查询范围,或者执行子查询开销较大的情况下,将这样的子查询放在最后执行可以在某种程度上提高整体的执行效率。也就是说,尽可能地使用其他查询条件最大程度地缩减查询范围之后,再执行子查询。

    4

    和表连接顺序相关的

    这些提示可以调整表连接的顺序。调整表连接的顺序并不是只能使用这些提示,在嵌套循环连接方式中也可以让提示来引导优化器使用由驱动查询条件所创建的索引。然而,该方法只有在使用的索引和表连接顺序同时被调整的情况下才比较有效。一般而言,这些提示主要在执行多表连接和表之间的连接顺序比较混乱的情况下才使用,也在排序合并连接或哈希连接方式下,为引导优化器优先执行数据量比较少得表时使用。

    • LEADING

    在一个多表关联的查询中,这个Hint指定由哪个表作为驱动表,即告诉优化器首先要访问那个表上的数据。引导优化器使用LEADING指定的表作为表连接顺序中的第一个表。该提示既与FROM中所描述的表的顺序无关,也与作为调整表连接顺序的ORDERED提示不同,并且在使用该提示时并不需要调整FROM中所描述的表的顺序。当该提示与ORDERED提示同时使用时,该提示被忽略。

    这个提示类似ORDERED提示,它允许指定驱动查询的表,然后由优化器来判断下一个要访问的表。如果使用这个提示指定多张表,那么就可以忽略这个提示。

    • ORDERED

    引导优化器按照FROM中所描述的表的顺序执行连接。如果和LEADING提示被一起使用,则LEADING提示将被忽略。由于ORDERED只能调整表连接的顺序并不能改变表连接的方式,所以为了改变表的连接方式,经常将USE_NL、USE_MERGE提示与ORDERED提示放在一起使用。

    5

    和表连接操作相关的

    • USE_NL

    使用该提示引导优化器按照嵌套循环连接方式执行表连接。它只是指出表连接的方式,对于表连接顺序不会有任何影响。

    • USE_MERGE

    引导优化器按照排序合并连接方式执行连接。在有必要的情况下,推荐将该提示与ORDERED提示一起使用。提示通常用于获得查询的最佳吞吐量。假设将两个表连接在一起,从每个表返回的行集将被排序,然后再被合并(也就是合并排序),从而组成最终的结果集。由于每个行先被排序之后才进行合并,所以在给定查询中检索所有行时,速度将会最快。如果需要以最快速度返回第一行,就应该使用USE_NL提示。

    • USE_HASH

    该提示引导优化器按照哈希连接方式执行连接。在执行哈希连接时,如果由于某一边的表比较小,从而可以在内存中实现哈希连接,那么就能够获得非常好的执行速度。由于在大部分情况下优化器会通过对统计信息的分析来决定Build Input和Prove Input,所以建议不要使用ORDERED提示随意改变表的连接顺序。但是当优化器没能做出正确判断时,或者像从嵌套视图中所获得的结果集合那样不具备统计信息时,可以使用该提示。

    6

    和并行相关的

    • PARALLEL

    指定SQL执行的并行度,这个值将会覆盖表自身设定的并行度。如果这个值为default,CBO使用系统参数。从表中读取大量数据和执行DML操作时使用该提示来指定SQL的并行操作。一般情况下需要在该提示中指定将要使用的并行线程个数。如果在该提示中没有指定并行度的个数,则优化器将使用PARALLEL_THREADS_PER_CPU参数所指定的值进行自动计算。如果在定义表时指定了PARALLEL,那么在能够使用并行操作的情况下,即使没有使用该提示,优化器也会按照指定的并行级别选择并行操作。但是如果想在DELETE、INSERT、UPDATE、MERGE等DML操作中使用并行操作,则必须要在会话中设置ALTER SESSION ENABLE PARALLEL DML。在某个会话中所设置的并行级别也可以被引用在内部的GROUP BY或者排序操作中。在并行操作中如果出现了某个限制要素,则该提示将被忽略。

    • NOPARALLEL/NO_PARALLEL

    在SQL语句禁止使用并行。在有些版本中用NO_PARALLEL提示来代替NOPARALLEL提示。

    • PQ_DISTRIBUTE

    为了提高并行连接的执行速度,使用该提示来定义使用何种方法在主从进程之间(例如生产者进程和消费者进程)分配各连接表的数据行。

    • PARALLEL_INDEX

    为了按照并行操作的方式对分区索引进行索引范围扫描而使用该提示,并且可以指定进程的个数。

    7

    其他相关的

    • APPEND

    让数据库以直接加载的方式(direct load)将数据加载入库。这个提示不会检查当前是否有插入所需要的块空间,相反它会直接将数据添加到新块中。这样会浪费空间,但可以提高插入的性能。需要注意的是,数据将被存储在HWM之上的位置。

    • APPEND_VALUES

    在11.2中,Oracle新增了APPEND_VALUES提示,使得INSERT INTO VALUES语句也可以使用直接路径插入。

    • CACHE

    在全表扫描之后,数据块将留在LRU列表的最活跃端。如果设置表的CACHE属性,它的作用和HINT一样。这个提示会将全表扫描全部缓存到内存中。如果表很大,会占用大量内存。因此适用于用户经常访问的较小的表。

    • NOCACHE

    引导优化器将通过全表扫描方式获取的数据块缓存在LRU列表的最后位置,这样可以让数据库实例缓存中的这些数据块被优先清除。这是优化器在Buffer Cache中管理数据块的默认方法(仅针对全表扫描)。

    • QB_NAME

    使用该提示为查询语句块命名,在其他查询语句块可以直接使用该查询语句块的名称。

    • DRIVING_SITE

    这个提示在分布式数据库操作中有用。指定表是处理连接所在的位置。可以限制通过网络处理的信息量。此外,还可以建立远程表的本地视图来限制从远程站点检索的行。本地视图应该有where子句,从而视图可以在将行发送回本地数据库之前限制从远程数据库返回的行。

    • DYNAMIC_SAMPLING

    提示SQL执行时动态采样的级别。这个级别为0~10,它将覆盖系统默认的动态采样级别。等级越高,所获得统计信息的准确率越高。该提示的功能就是为了确保将动态采样原理应用在单个SQL中。

    • AND_EQUAL

    这个提示会使优化器合并表上的多个索引,而不是选择其中最好的索引(这是INDEX提示的用途)。这个提示与前面的INDEX_JOIN提示有区别,以此指定的合并索引随后需访问表,而INDEX_JOIN提示则只需访问索引。如果发现需经常用到这个提示,可能需要删除这些单个索引而改用一个组合索引。需要查询条件里面包括所有索引列,然后取得每个索引中得到的rowid列表。然后对这些对象做merge join,过滤出相同的rowid后再去表中获取数据或者直接从索引中获得数据。在10g中,and_equal已经废弃了,只能通过hint才能生效。

    • CARDINALITY

    向优化器提供对某个查询语句的整体或部分的预测基数值,并通过参考该基数值来为查询语句制定执行计划。如果在该提示中没有指定表的名称,则该基数值将被视为从该查询语句所获得的最终结果行数。

    四、Hint使用示例

    下面通过一个例子说明一下提示的使用及在什么情况下提示会被忽略。

    (1).构建表

    (2).使用INDEX提示

    SQL优化:一篇文章说清楚Oracle Hint的正确使用姿势

    *在某些情况下,如果CBO认为Hint会导致错误结果,那么Hint则会忽略。该例子中因为ID字段可能为空,而索引是保存空值的,因此count(*)使用索引将导致错误的结果,故而使用了全表扫描,忽略了Hint。

    (3).使用INDEX提示(非空字段)

    SQL优化:一篇文章说清楚Oracle Hint的正确使用姿势

    *ID字段不可为空,因此COUNT可用索引扫描的方式处理,Hint生效了。

    展开全文
  • 1)Hint 是Oracle 提供的一种SQL语法,它允许用户在SQL语句中插入相关的语法,从而影响SQL的执行方式。2)Oracle 数据库中优化器(Optimizer)是SQL分析和执行的优化工具,它负责指定SQL的执行计划,也就是它负责保证SQL...

    1)Hint 是Oracle 提供的一种SQL语法,它允许用户在SQL语句中插入相关的语法,从而影响SQL的执行方式。

    2)Oracle 数据库中优化器(Optimizer)是SQL分析和执行的优化工具,它负责指定SQL的执行计划,也就是它负责保证SQL执行的效率最高,比如优化器决定Oracle 以什么样的方式来访问数据,是全表扫描(Full Table Scan),索引范围扫描(Index Range Scan)还是全索引快速扫描(INDEX Fast Full Scan:INDEX_FFS);对于表关联查询,它负责确定表之间以一种什么方式来关联,比如HASH_JOHN还是NESTED LOOPS 或者MERGE JOIN。 这些因素直接决定SQL的执行效率,所以优化器是SQL 执行的核心,它做出的执行计划好坏,直接决定着SQL的执行效率。Oracle 的优化器有两种:

    RBO(Rule-Based Optimization): 基于规则的优化器

    CBO(Cost-Based Optimization): 基于代价的优化器

    3)在Oracle 10g中,CBO 可选的运行模式有2种:

    (1)       FIRST_ROWS(n)

    (2)       ALL_ROWS  -- 10g中的默认值

    4) 其他方面的一些Hint

    APPEND HINT

    提示数据库以直接加载的方式(direct load)将数据加载入库。

    示例:

    Insert /*+append */ into t as select * from all_objects;

    这个hint 用的比较多。 尤其在插入大量的数据,一般都会用此hint。

    5)Hint Hint 语法

    优化器模式提示 ALL_ROWS Hint

    FIRST_ROWS Hint

    RULE Hint

    访问路径提示 CLUSTER Hint

    FULL Hint

    HASH Hint

    INDEX Hint

    NO_INDEX Hint

    INDEX_ASC Hint

    INDEX_DESC Hint

    INDEX_COMBINE Hint

    INDEX_FFS Hint

    INDEX_SS Hint

    INDEX_SS_ASC Hint

    INDEX_SS_DESC Hint

    NO_INDEX_FFS Hint

    NO_INDEX_SS Hint

    ORDERED Hint

    LEADING Hint

    USE_HASH Hint

    NO_USE_HASH Hint

    表连接顺序提示 USE_MERGE Hint

    NO_USE_MERGE Hint

    USE_NL Hint

    USE_NL_WITH_INDEX Hint

    NO_USE_NL Hint

    表关联方式提示 PARALLEL Hint

    NO_PARALLEL Hint

    PARALLEL_INDEX Hint

    NO_PARALLEL_INDEX Hint

    PQ_DISTRIBUTE Hint

    并行执行提示 FACT Hint

    NO_FACT Hint

    MERGE Hint

    NO_MERGE Hint

    NO_EXPAND Hint

    USE_CONCAT Hint

    查询转换提示 REWRITE Hint

    NO_REWRITE Hint

    UNNEST Hint

    NO_UNNEST Hint

    STAR_TRANSFORMATION Hint

    NO_STAR_TRANSFORMATION Hint

    NO_QUERY_TRANSFORMATION Hint

    APPEND Hint

    NOAPPEND Hint

    CACHE Hint

    NOCACHE Hint

    CURSOR_SHARING_EXACT Hint

    其他Hint DRIVING_SITE Hint

    DYNAMIC_SAMPLING Hint

    PUSH_PRED Hint

    NO_PUSH_PRED Hint

    PUSH_SUBQ Hint

    NO_PUSH_SUBQ Hint

    PX_JOIN_FILTER Hint

    NO_PX_JOIN_FILTER Hint

    NO_XML_QUERY_REWRITE Hint

    QB_NAME Hint

    MODEL_MIN_ANALYSIS Hint

    展开全文
  • 表的连接方式USE_NL HintFor example:SELECT /*+ USE_NL(l h) */ h.customer_id, l.unit_price * l.quantityFROM orders h, order_items lWHERE l.order_id = h.order_id;USE_HASH HintFor example:SELECT /*+ USE_...
  • inline hint improvement

    2021-01-12 06:00:49
    <div><p>Our current project makes heavy use of <code>inline hint, but because of vscode api's limitation, our <code>inline hint</code> is worse than intellij's <code>inline hint</code>. I have...
  • oracle hint

    2019-07-10 09:49:48
    Oracle中Hint深入理解(原创) 博客分类: Oracle Tuning Hint概述 基于代价的优化器是很聪明的,在绝大多数情况下它会选择正确的优化器,减轻了DBA的负担。但有时它也聪明反被聪明误,选择了很差的执行计划,使...
  • <div><p>If any part of a hint is typed as uppercase (i.e. with the shift key held down), open the hint in a new tab. <p>Fixes #392 <p>My rationale for this change: <p>This functionality was described ...
  • tooltip wait time is around 60 seconds after the hint is available, so it is expected that it will appear after the hint is visible. <strong>Observed behaviour: Both (hint and tooltip) are appearing ...
  • --mysql常用的hint-------------------2014/06/26对于经常使用oracle的朋友可能知道,oracle的hint功能种类很多,对于优化sql语句提供了很多方法。同样,在mysql里,也有类似的hint功能。下面介绍一些常用的。强制...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 33,523
精华内容 13,409
热门标签
关键字:

hint