简体   繁体   English

Oracle查询优化推荐

[英]Oracle query optimization recommendation

Below query is just taking long time and the below predicate is used only to get unique records, as such was wondering is there a different way to rewrite the same query without calling the below predicate multiple times, to get the unique ID.下面的查询只需要很长时间,下面的谓词仅用于获取唯一记录,因此想知道是否有不同的方法来重写相同的查询,而无需多次调用下面的谓词来获取唯一 ID。

select max(c.id) from plocation c where c.ids = y.ids and c.idc = y.idc)
select max(cr.id) from plocation_log cr where cr.ids = yt.ids and cr.idc = yt.idc)
select max(pr.id) from patentpr where pr.ids = p.ids and pr.idc = p.idc)           

My full sample query我的完整示例查询

SELECT to_char(p.pid) AS patentid,
       p.name,
       x.dept,
       y.location
  FROM patent p
  JOIN pdetails x ON p.pid = x.pid  AND x.isactive = 1
  JOIN plocation y
            ON y.idr = p.idr
           AND y.idc = p.idc
           AND y.id = *(select max(c.id) from plocation c where c.ids = y.ids and c.idc = y.idc)*
           AND y.idopstype in (36, 37)
   JOIN plocation_log yt
            ON yt.idr = y.idr
           AND yt.idc= y.idc
           AND yt.id = *(select max(cr.id) from plocation_log cr where cr.ids = yt.ids and cr.idc = yt.idc)*
           AND yt.idopstype in (36,37)
WHERE
      p.idp IN (10,20,30)
   AND p.id = *(select max(pr.id) from patent pr where pr.ids = p.ids and pr.idc = p.idc)*
   AND p.idopstype in (36,37)

As commented by The Impaler, one option is to use analytic functions instead of correlated subqueries.正如 The Impaler 所评论的,一种选择是使用分析函数而不是相关子查询。 The idea is to rank records within subqueries using RANK() , then filter in the outer query (join conditions or WHERE clause).这个想法是使用RANK()查询中的记录进行排名,然后在外部查询(连接条件或WHERE子句)中进行过滤。

Consider:考虑:

SELECT to_char(p.pid) AS patentid,
       p.name,
       x.dept,
       y.location
  FROM (SELECT p.*, RANK() OVER(PARTITION BY ids, idc ORDER BY id) rn FROM patinet) p
  JOIN pdetails x ON p.pid = x.pid  AND x.isactive = 1
  JOIN (SELECT y.*, RANK() OVER(PARTITION BY ids, idc ORDER BY id) rn FROM plocation y) y
            ON y.idr = p.idr
           AND y.idc = p.idc
           AND y.idopstype in (36, 37)
           AND y.rn = 1
   JOIN (SELECT y.*, RANK() OVER(PARTITION BY ids, idc ORDER BY id) rn FROM plocation_log yt) yt
            ON yt.idr = y.idr
           AND yt.idc= y.idc
           AND yt.idopstype in (36,37)
           AND yt.rn = 1
WHERE
   p.idp IN (10,20,30)
   AND p.idopstype in (36,37)
   AND p.rn = 1
   

Consider joining to aggregate CTEs to calculate MAX values per group once as opposed to rowwise MAX calculation for every outer query row.考虑加入聚合 CTE 以计算每个组的MAX一次,而不是为每个外部查询行进行行MAX计算。 Also, be sure to use more informative table aliases instead of a, b, c or x, y, z style.此外,请务必使用信息量更大的表别名,而不是a, b, cx, y, z样式。

WITH loc_max AS
  (select ids, idc, max(id) as max_id from plocation group ids, idc)    
 ,   log_max AS    
  (select ids, idc, max(id) as max_id from plocation_log group by ids, idc)
 ,   pat_max AS
  (select ids, idc, max(id) as max_id from patent pr group by ids, idc)

SELECT to_char(pat.pid) AS patentid
       , pat.name
       , det.dept
       , loc.location
  FROM patent pat
  JOIN pdetails det
    ON pat.pid  = det.pid  
    AND det.isactive = 1
  JOIN plocation loc
    ON  loc.idr = pat.idr
    AND loc.idc = pat.idc
    AND loc.idopstype IN (36, 37)
  JOIN loc_max                              -- ADDED CTE JOIN
    ON  loc.id  = loc_max.max_id
    AND loc.ids = loc_max.ids 
    AND loc.idc = loc_max.idc
   
  JOIN plocation_log log
    ON  log.idr = log.idr
    AND log.idc = log.idc
    AND log.idopstype in (36,37)
  JOIN log_max                              -- ADDED CTE JOIN
    ON  log.id  = log_max.max_id
    AND log.ids = log_max.ids
    AND log.idc = log_max.idc

  JOIN pat_max                              -- ADDED CTE JOIN
    ON  pat.id  = pat_max.max_id
    AND pat.ids = pat_max.ids 
    AND pat.idc = pat_max.idc

WHERE pat.idp IN (10, 20, 30)
  AND pat.idopstype IN (36, 37)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM