Oracle 中内联视图的性能问题

发布于 2024-12-14 07:50:09 字数 788 浏览 2 评论 0原文

我有一个如下所示的查询,表 A、T、S 有大约 100 万行,而 P 有超过 1 亿行。我新在这个查询中引入了内联视图“temp”,它导致性能急剧下降。为 temp 检索的数据几乎没有 50 行,并且该内联查询在单独执行时快速运行。

自动跟踪统计数据显示,添加此内容后,“一致获取”的数量从引入 temp 之前的 6 位数字变为 9 位数字!此外,超过 90% 的 LAST_CR_BUFFER_GETS 都属于“临时”视图。如果我从此视图中提取数据到临时表中,并使用该表作为连接的一部分,性能会非常好,但该解决方案对我来说并不可行。

我知道这个问题非常普遍,但我想知道使用这个内联视图是否有什么小错误。 内联视图不会提供与将这些数据存储在临时表中相同的性能吗? 有什么方法可以提示 Oracle 有效地使用此视图,从而提高性能。

   select t.id, 
          a.date
     from A a,
          T t,
          P p,
          S s,
          (select id 
             from S, 
                  R 
            where s.id = r.id 
              and r.code  = 10
                  r.code1 = 20
                  r.name  = 'string1' ) temp
    where ...cond1
          ...cond2
          ...cond2
    s.id = temp.id

I have a query that looks like below and the tables A,T,S have around 1 million rows whereas P have more than 100 million rows. I've newly introduced the inline view "temp" into this query and it caused a drastic degradation in performance. The data retrieved for temp is hardly 50 rows and this inline query runs in a snap when executed alone.

The autotrace statistics show a huge increase in the number of "consistent gets" from a 6 digit number before introducing temp to a 9 digit number after adding this!! Also, more than 90% of LAST_CR_BUFFER_GETS are accounted for the "temp" view. If I extract the data from this view into a temporary table and use that table as part of the joins the performance is very good but that solution is not really feasible for me.

I know the question is very generalized but I'm wondering if there is anything trivially wrong in using this inline view.
Doesn't inline views give the same performance like having this data in a temporary table?
Is there any way I can hint Oracle to use this view in a effective manner and thus increasing performance.

   select t.id, 
          a.date
     from A a,
          T t,
          P p,
          S s,
          (select id 
             from S, 
                  R 
            where s.id = r.id 
              and r.code  = 10
                  r.code1 = 20
                  r.name  = 'string1' ) temp
    where ...cond1
          ...cond2
          ...cond2
    s.id = temp.id

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凑诗 2024-12-21 07:50:09

根据我的调优经验,最好的猜测是,它可能会根据通过连接 A、t、p、s 获得的结果集匹配的每个记录来评估内联视图“temp”一次。
这里最好的解决方案是这样重写。
请记住,ORDERED 提示假定您按照希望连接的顺序在 FROM 子句中提供表。
我首先列出了 temp 和 s,因为这是您列出 temp.id = s.id 的唯一连接条件。
另外,我假设您在作为连接条件一部分的所有其他列上都有索引。如果您还有其他问题,请告诉我。

select  /*+ ordered use_nl(a t p s) */
    t.id,  a.date
from    (
    select  id 
    from    S, 
        R
    where   s.id = r.id and r.code  = 10 r.code1 = 20 r.name  = 'string1' 
    ) temp,
    S s,
    A a,
    T t,
    P p
where   ...cond1 ...cond2 ...cond2 and s.id = temp.id

Best guess, based on my tuning experience is it's probably evaluating the inline view "temp" once per records matched from the result-set obtained by joining A, t, p, s.
The best solution here is to re-write it this way.
Keep in mind that the ORDERED hint assumes that you are providing the tables in the FROM clause in the order in which you want them to join.
I've listed temp and s first, cos that's the only join condition you have listed temp.id = s.id.
Also I'm assuming you have indexes on all the other columns that are part of the join criteria. Let me know if you have any more questions.

select  /*+ ordered use_nl(a t p s) */
    t.id,  a.date
from    (
    select  id 
    from    S, 
        R
    where   s.id = r.id and r.code  = 10 r.code1 = 20 r.name  = 'string1' 
    ) temp,
    S s,
    A a,
    T t,
    P p
where   ...cond1 ...cond2 ...cond2 and s.id = temp.id
凉栀 2024-12-21 07:50:09
WITH TEMP AS
(select id 
         from S, 
              R 
        where s.id = r.id 
          and r.code  = 10
              r.code1 = 20
              r.name  = 'string1' )
select t.id, 
      a.date
 from A a,
      T t,
      P p,
      S 
where ...cond1
      ...cond2
      ...cond2
 s.id = temp.id;

尝试运行此查询,并请提供此查询的解释计划

WITH TEMP AS
(select id 
         from S, 
              R 
        where s.id = r.id 
          and r.code  = 10
              r.code1 = 20
              r.name  = 'string1' )
select t.id, 
      a.date
 from A a,
      T t,
      P p,
      S 
where ...cond1
      ...cond2
      ...cond2
 s.id = temp.id;

try to run this query , and please provide the explain plan for this query

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文