我刚刚熟悉了"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'
)
我已经搜索过它,但这些文章并不是那么实用,所以我决定在这里询问这个提示。我的问题是:
- 对 有什么显着影响
performance
吗? - 这里有人在他们的查询中使用过这个提示吗?为什么 ?
- 在什么情况下我们必须使用这个提示?
提前致谢
完全没有性能影响,但它可以更容易地遵循复杂的查询计划并提示特定的子查询(即可能让您更轻松地改进性能)。
我不时使用它,主要是在我演示执行计划时,因为添加位时子查询将保留查询块名称。
没有任何情况需要您使用提示。
为查询块提供您自己的名称来代替优化器生成的
SEL$1
,等会很有用。SEL$2
它也可能更可靠,例如,如果您的顶级提示按名称引用子块,但系统生成的编号稍后会由于对查询的编辑而更改,从而使您的/*+ full(e@sel$5) */
提示变得毫无意义。无提示查询:
计划包括:
现在如果我们使用 qblock_name 来命名子查询块,并在顶层引用它:
计划的同一部分变为:
提示报告 (19c) 还显示了命名块:
尽管这是一个简单而人为的示例,但您可以看到命名查询块如何更容易在顶层整合提示。
文档说它用于命名 SQL 块。
这似乎更适合那些调整 SQL 的人,而不是 CBO。
答案
我得检查一下。但是,如果 CTE 名称未显示在计划中,那将是放置它的好地方。(我通常在一个 SQL 语句中使用至少 5 个 CTE。)