简体   繁体   English

如何提高迭代循环的性能

[英]How to Improve performance of iteration loops

I have a java method which finds all children (leaves) of a parent.我有一个 java 方法可以找到父母的所有孩子(叶子)。 It works ok.but there is performance issue.它工作正常。但存在性能问题。 How can i make it work faster?我怎样才能让它更快地工作? When the children gets large it becomes problematic.孩子长大了,问题就来了。 Here is the method:这是方法:

Private void getChildren(String orgId, List<String> children, List<String> organs, int j){
Query query= entityManager.createNativeQuery("select c.organization_id from organization c where c.parent_org_id="+orgId);
if(query.getResultList().size()>0)
  organs.addAll((List<String>) query.getResultList());
else
  children.add(orgId);
for(int i=j+1; i<organs.size();i++){
j=i;
query=entityManager.createNativeQuery("select c.organization_id from organization c where c.parent_org_id="+String.valueOf(organs.get(i)));
if(query.getResultList().size()>0)
  organs.addAll((List<String>) query.getResultList());
else
  children.add(String.valueOf(organs.get(i)));
}
}

I call this method like我称这种方法为

getChildren("68",new ArrayList<>(),new ArrayList<>(),-1)

I have oracle as database so if it is better to acheive this via oracle query please note me.我有 oracle 作为数据库,所以如果最好通过 oracle 查询来实现这一点,请注意我。 By the way my spring version doesn't support streams!顺便说一句,我的 spring 版本不支持流!

You basically have a 1+N select problem (issue a single query for each id in your collection).您基本上有一个 1+N select 问题(为您的集合中的每个 id 发出一个查询)。 Don't do this, instead use the IN clause and issue a single query..不要这样做,而是使用IN子句并发出单个查询。

Another thing you shouldn't be doing is use concat for your query creation, never do this!您不应该做的另一件事是使用 concat 创建查询,永远不要这样做! What you should do is just return the result and use a query with an IN clause.您应该做的只是返回结果并使用带有IN子句的查询。

String query = "select c.organization_id from organization c where c.parent_org_id IN (:ids))
return em.createNativeQuery(query).setParameters("ids", organs);

or even better use a single query altogether.甚至更好地完全使用单个查询。 You can use a self join for that)您可以为此使用自加入)

String query = "SELECT c1.organization_id " +
               "FROM organization c1 LEFT OUTER JOIN organization c2 " +
               "ON c1.parent_org_id=c2.organization_id " +
               "WHERE c2.parent_org_id=?"; 
return em.createNativeQuery(query, String.class).setParameter(1, orgId).getResultList();

Judging from your solution I would strongly recommend studying SQL and JPA.从您的解决方案来看,我强烈建议您学习 SQL 和 JPA。

Try it in a big query在大查询中尝试

select c.organization_id from organization, (
select c.organization_id as sub1 from organization c where c.parent_org_id="+orgId +") as x_ where organization.parent_org_id = x_.sub1

The reason why it is slow, is that you query the database for every child.速度慢的原因是您为每个孩子查询数据库。 This is very inefficient, I assume even the load on the database will be smaller.这是非常低效的,我假设即使数据库上的负载也会更小。

Answer provided by Deinum only gets the direct children. Deinum 提供的答案只得到直接的孩子。 Whereas my java method returns all children including nested ones.而我的 java 方法返回所有子项,包括嵌套的子项。

I have found a query for that which is much more optimized than my java method.我找到了一个比我的 java 方法优化得多的查询。 It uses temporary tables:它使用临时表:

with temp_tbl (id,parent_id) as 
(
select organization_id,parent_org_id from organization where parent_org_id =? 
union all 
select c.organization_id ,c.parent_org_id from organization c join temp_tbl t on t.id=c.parent_org_id and t.parent_id !=t.id
)
Select to_char(g.id) from temp_tbl g 

At the end i return to_char(g.id) to make it a string instead of big decimal.最后,我返回to_char(g.id)以使其成为字符串而不是大十进制。 Because em.createNativeQuery(query, String.class) didn't turn it to string and threw error for me.因为em.createNativeQuery(query, String.class)没有将其转换为字符串并为我抛出错误。 So just use em.createNativeQuery(query)所以只需使用em.createNativeQuery(query)

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

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