oracle查询优化建议

1bqhqjot  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(392)

below查询只需要很长时间,而below predicate 只用于获取唯一的记录,因此想知道是否有其他方法可以重写同一个查询而不多次调用below predicate 来获取唯一的id。

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

我的完整示例查询

  1. SELECT to_char(p.pid) AS patentid,
  2. p.name,
  3. x.dept,
  4. y.location
  5. FROM patent p
  6. JOIN pdetails x ON p.pid = x.pid AND x.isactive = 1
  7. JOIN plocation y
  8. ON y.idr = p.idr
  9. AND y.idc = p.idc
  10. AND y.id = *(select max(c.id) from plocation c where c.ids = y.ids and c.idc = y.idc)*
  11. AND y.idopstype in (36, 37)
  12. JOIN plocation_log yt
  13. ON yt.idr = y.idr
  14. AND yt.idc= y.idc
  15. AND yt.id = *(select max(cr.id) from plocation_log cr where cr.ids = yt.ids and cr.idc = yt.idc)*
  16. AND yt.idopstype in (36,37)
  17. WHERE
  18. p.idp IN (10,20,30)
  19. AND p.id = *(select max(pr.id) from patent pr where pr.ids = p.ids and pr.idc = p.idc)*
  20. AND p.idopstype in (36,37)
yuvru6vn

yuvru6vn1#

考虑加入聚合CTE以计算 MAX 每组值一次,而不是按行 MAX 计算每个外部查询行。另外,请确保使用更多的信息表别名,而不是 a, b, c 或者 x, y, z 风格。

  1. WITH loc_max AS
  2. (select ids, idc, max(id) as max_id from plocation group ids, idc)
  3. , log_max AS
  4. (select ids, idc, max(id) as max_id from plocation_log group by ids, idc)
  5. , pat_max AS
  6. (select ids, idc, max(id) as max_id from patent pr group by ids, idc)
  7. SELECT to_char(pat.pid) AS patentid
  8. , pat.name
  9. , det.dept
  10. , loc.location
  11. FROM patent pat
  12. JOIN pdetails det
  13. ON pat.pid = det.pid
  14. AND det.isactive = 1
  15. JOIN plocation loc
  16. ON loc.idr = pat.idr
  17. AND loc.idc = pat.idc
  18. AND loc.idopstype IN (36, 37)
  19. JOIN loc_max -- ADDED CTE JOIN
  20. ON loc.id = loc_max.max_id
  21. AND loc.ids = loc_max.ids
  22. AND loc.idc = loc_max.idc
  23. JOIN plocation_log log
  24. ON log.idr = log.idr
  25. AND log.idc = log.idc
  26. AND log.idopstype in (36,37)
  27. JOIN log_max -- ADDED CTE JOIN
  28. ON log.id = log_max.max_id
  29. AND log.ids = log_max.ids
  30. AND log.idc = log_max.idc
  31. JOIN pat_max -- ADDED CTE JOIN
  32. ON pat.id = pat_max.max_id
  33. AND pat.ids = pat_max.ids
  34. AND pat.idc = pat_max.idc
  35. WHERE pat.idp IN (10, 20, 30)
  36. AND pat.idopstype IN (36, 37)
展开查看全部
06odsfpq

06odsfpq2#

正如impaler所评论的,一种选择是使用分析函数而不是相关的子查询。其思想是使用 RANK() ,然后筛选外部查询(连接条件或 WHERE 条款)。
考虑:

  1. SELECT to_char(p.pid) AS patentid,
  2. p.name,
  3. x.dept,
  4. y.location
  5. FROM (SELECT p.*, RANK() OVER(PARTITION BY ids, idc ORDER BY id) rn FROM patinet) p
  6. JOIN pdetails x ON p.pid = x.pid AND x.isactive = 1
  7. JOIN (SELECT y.*, RANK() OVER(PARTITION BY ids, idc ORDER BY id) rn FROM plocation y) y
  8. ON y.idr = p.idr
  9. AND y.idc = p.idc
  10. AND y.idopstype in (36, 37)
  11. AND y.rn = 1
  12. JOIN (SELECT y.*, RANK() OVER(PARTITION BY ids, idc ORDER BY id) rn FROM plocation_log yt) yt
  13. ON yt.idr = y.idr
  14. AND yt.idc= y.idc
  15. AND yt.idopstype in (36,37)
  16. AND yt.rn = 1
  17. WHERE
  18. p.idp IN (10,20,30)
  19. AND p.idopstype in (36,37)
  20. AND p.rn = 1
展开查看全部

相关问题