Oracle

在查詢中使用“qb_name()”提示(查詢塊名稱)對性能有顯著影響嗎?

  • November 14, 2021

我剛剛熟悉了"qb_name" (query block name)Oracle 中的提示,下面您可以看到在查詢中使用此提示的範例:

select
       /*+
               qb_name(main)
       */
       ord.id,
       ord.valuation,
       ord.status,
       (select /*+ qb_name(company) */ max(com.name)  from companies  com  where com.id  = ord.id_company) company,
       (select /*+ qb_name(product) */ max(prd1.name) from products   prd1 where prd1.id = orl.id_product) product,
       orl.quantity
from
       orders          ord,
       order_lines     orl
where
       ord.date_placed > trunc(sysdate) - 7
and     orl.id_ord = ord.id
and     orl.id_product in (
               select  /*+ qb_name(class) */
                       prd2.id
               from    products prd2
               where   prd2.class = 'Group25'
       )

我已經搜尋過它,但這些文章並不是那麼實用,所以我決定在這裡詢問這個提示。我的問題是:

  1. 對 有什麼顯著影響performance嗎?
  2. 這裡有人在他們的查詢中使用過這個提示嗎?為什麼 ?
  3. 在什麼情況下我們必須使用這個提示?

提前致謝

為查詢塊提供您自己的名稱來代替優化器生成的SEL$1,等會很有用。SEL$2它也可能更可靠,例如,如果您的頂級提示按名稱引用子塊,但係統生成的編號稍後會由於對查詢的編輯而更改,從而使您的/*+ full(e@sel$5) */提示變得毫無意義。

無提示查詢:

select * from emp e
where  e.deptno in
      ( select d.deptno
        from   dept d
        where  d.loc = 'DALLAS' )
and    e.job = 'ANALYST';

計劃包括:

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

  3 - SEL$5DA710D3 / E@SEL$1
  4 - SEL$5DA710D3 / D@SEL$2
  5 - SEL$5DA710D3 / D@SEL$2

Outline Data
-------------

 /*+
     BEGIN_OUTLINE_DATA
     IGNORE_OPTIM_EMBEDDED_HINTS
     OPTIMIZER_FEATURES_ENABLE('19.1.0')
     DB_VERSION('19.1.0')
     ALL_ROWS
     OUTLINE_LEAF(@"SEL$5DA710D3")
     UNNEST(@"SEL$2")
     OUTLINE(@"SEL$1")
     OUTLINE(@"SEL$2")
     FULL(@"SEL$5DA710D3" "E"@"SEL$1")
     INDEX(@"SEL$5DA710D3" "D"@"SEL$2" ("DEPT"."DEPTNO"))
     LEADING(@"SEL$5DA710D3" "E"@"SEL$1" "D"@"SEL$2")
     USE_NL(@"SEL$5DA710D3" "D"@"SEL$2")
     NLJ_BATCHING(@"SEL$5DA710D3" "D"@"SEL$2")
     END_OUTLINE_DATA
 */

現在如果我們使用 qblock_name 來命名子查詢塊,並在頂層引用它:

select /*+ index(d@deptsubq(dept.loc)) */ * from emp e
where  e.deptno in
      ( select /*+ qb_name(deptsubq) */ d.deptno
        from   dept d
        where  d.loc = 'DALLAS' )
and    e.job = 'ANALYST';

計劃的同一部分變為:

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

  3 - SEL$F31E4C0D / E@SEL$1
  4 - SEL$F31E4C0D / D@DEPTSUBQ
  5 - SEL$F31E4C0D / D@DEPTSUBQ

Outline Data
-------------

 /*+
     BEGIN_OUTLINE_DATA
     IGNORE_OPTIM_EMBEDDED_HINTS
     OPTIMIZER_FEATURES_ENABLE('19.1.0')
     DB_VERSION('19.1.0')
     ALL_ROWS
     OUTLINE_LEAF(@"SEL$F31E4C0D")
     UNNEST(@"DEPTSUBQ")
     OUTLINE(@"SEL$1")
     OUTLINE(@"DEPTSUBQ")
     FULL(@"SEL$F31E4C0D" "E"@"SEL$1")
     INDEX(@"SEL$F31E4C0D" "D"@"DEPTSUBQ" ("DEPT"."LOC"))
     LEADING(@"SEL$F31E4C0D" "E"@"SEL$1" "D"@"DEPTSUBQ")
     USE_NL(@"SEL$F31E4C0D" "D"@"DEPTSUBQ")
     NLJ_BATCHING(@"SEL$F31E4C0D" "D"@"DEPTSUBQ")
     END_OUTLINE_DATA
 */

提示報告 (19c) 還顯示了命名塊:

Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 2
---------------------------------------------------------------------------

  0 -  DEPTSUBQ
          -  qb_name(deptsubq)

  4 -  SEL$F31E4C0D / D@DEPTSUBQ
          -  index(d@deptsubq(dept.loc))

儘管這是一個簡單而人為的範例,但您可以看到命名查詢塊如何更容易在頂層整合提示。

引用自:https://dba.stackexchange.com/questions/302522