【问题标题】:Oracle query time optimizationOracle 查询时间优化
【发布时间】:2016-07-16 02:12:58
【问题描述】:

如何优化下面的查询时间(超过1h)?我只能访问表视图,无法检查查询计划和视图索引。我只能更改查询符号。表“c”有超过 32 亿条记录。

SELECT
a.APPLICATIONNUMBER,c.NEWSTATUSSYMBOL,c.MODDATE,c.NEXT_MODDATE
FROM a
LEFT JOIN 
(SELECT
c000.ID,c000.NEWSTATUSSYMBOL,c000.MODDATE,c000.NEXT_MODDATE
FROM
(SELECT
c00.ID,c00.NEWSTATUSSYMBOL,c00.MODDATE,LEAD(c00.MODDATE,1) OVER (ORDER BY c00.ID, c00.MODDATE) AS NEXT_MODDATE
FROM
(SELECT
c0.ID,c0.STATUSSYMBOL,c0.NEWSTATUSSYMBOL,c0.MODDATE
FROM c0
WHERE (c0.STATUSSYMBOL in ('State1','State2','State3') OR c0.NEWSTATUSSYMBOL in ('State1','State2','State3'))                                                                    
AND c0.TYPEID = 1
AND c0.HDB_START >= '15/01/01'
AND c0.HDB_LAST      = 'Y')c00
)c000
WHERE
c000.NEWSTATUSSYMBOL in ('State1','State2','State3')) c
ON a.ID = c.ID

WHERE
a.APPLICATIONNUMBER like 'P%'
AND a.APPLICATIONSTATUSSYMBOL in ('State4','State5','State6')
AND a.APPLICATIONDATE           >= to_timestamp('2015-01-01 00:00:01')
AND a.MODIFIEDDATE >= to_timestamp('2016-07-04 00:00:01')
AND a.MODIFIEDDATE <= to_timestamp('2016-07-10 23:59:59')
AND a.HDB_LAST                 = 'Y';

【问题讨论】:

  • 请使用谓词发布计划查询
  • 我在 db 中无权检查查询计划 :(
  • 我想索引在 a.ID、c.ID、c0.HDB_START 上。
  • 那么你不应该做数据库优化。就像试图让汽车更快地改变油漆一样。你需要调整引擎。
  • 可惜了。想想看。我们不确切知道存在哪些索引、访问路径和过滤器。我可以说超过 10 种情况,从不正确的语法到 Oracle 错误(难以检测)和收集到的直方图统计数据错误。

标签: sql oracle optimization


【解决方案1】:

在这里猜测一下。如上所述,没有您猜测的查询计划和索引,而且我没有您的表或数据。但是下面的查询是同一个查询吗?看起来他们是 2 个表,你是外部加入 co,a 是正确的吗? coo 和 c 是在 co 之上的查询吗?所以你能和co对抗一次吗?

WITH t1
     AS (SELECT ID,
                STATUSSYMBOL,
                NEWSTATUSSYMBOL,
                MODDATE
           FROM c0
          WHERE     TYPEID = 1
                AND HDB_START >= '15/01/01'
                AND HDB_LAST = 'Y'
                AND (   STATUSSYMBOL IN ('State1', 'State2', 'State3')
                     OR NEWSTATUSSYMBOL IN ('State1', 'State2', 'State3'))),
     t2
     AS (SELECT APPLICATIONNUMBER, ID
           FROM a
          WHERE     a.APPLICATIONNUMBER LIKE 'P%'
                AND a.APPLICATIONSTATUSSYMBOL IN ('State4',
                                                  'State5',
                                                  'State6')
                AND a.APPLICATIONDATE >= TO_TIMESTAMP ('2015-01-01 00:00:01')
                AND a.MODIFIEDDATE >= TO_TIMESTAMP ('2016-07-04 00:00:01')
                AND a.MODIFIEDDATE <= TO_TIMESTAMP ('2016-07-10 23:59:59')
                AND a.HDB_LAST = 'Y')
SELECT t2.APPLICATIONNUMBER,
       t1.NEWSTATUSSYMBOL,
       t1.MODDATE,
       LEAD (t1.MODDATE, 1) OVER (ORDER BY t1.ID) AS NEXT_MODDATE
  FROM t1 LEFT JOIN t2 ON t1.ID = t2.ID

【讨论】:

  • 如果您不确定发布的查询是否实际上与原始查询相同,您可以执行第一个查询减去第二个查询联合所有第二个查询减去第一个查询并确保没有任何结果回来,但它会永远运行。在我通过重写优化查询之后,如果它实际上是在提取相同的数据,我之前不是肯定的。
  • 查询与旧查询相同且更快。
猜你喜欢
  • 1970-01-01
  • 2021-09-13
  • 2015-02-26
  • 2011-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多