gpt4 book ai didi

java - 性能二1 :N grouping methods

转载 作者:行者123 更新时间:2023-11-30 02:04:26 26 4
gpt4 key购买 nike

假设我们有两个 1:N 关系的表。现在假设在 java 方面您希望将结果数据构造为如下所示:

class ParentDto {
public Long id;
public String someColumn;
public List<ChildDto> children = new ArrayList<>();
}

class ChildDto {
public Long id;
public Long parentId;
public String someColumn;
}

理论上,执行单个 SQL 查询是否更快:

SELECT * 
FROM PARENT_DTO
JOIN CHILD_DTO ON PARENT_DTO.ID = CHILD_DTO.PARENT_ID

然后在java端像这样执行分组操作

// assume that query is some api to run a query like jdbc that returns theortical type List<Row>
List<ParentDto> results = query(/* query above*/).stream()
// assume that first value in row is ParentDto::id
.collect(groupingBy(row -> (Long) row.get(0)))
// after collect stream type is Map<Long, List<Row>>, whatever row type is from whatever api
.values()
.stream()
// listOfGroupRows is just List<Row>
.map(listOfGroupedRows -> {
// assume that ParentDto constructor knows how to fetch values from first row
ParentDto rowValue = new ParentDto(listOfGroupedRows.get(0))
// assume that ChildDto constructor knows how to fetch values from each row
rowValue.children = listOfGroupedRows.stream()
.map(row -> new ChildDto(row))
.collect(toList())
})

仅运行两个单独的查询是否更快:

SELECT *
FROM PARENT_DTO

SELECT *
FROM CHILD_DTO

然后在java端执行如下分组操作:

Map<Long, List<ChildDto>> children = query(/* second query */).stream()
.map(r -> new ChildDto(r))
.collect(groupingBy(ChildDto::parentId));

List<ParentDto> results = query(/* first query */).stream()
.map(r -> {
ParentDto dto = new ParentDto(r);
dto.children = children.get(dto.id);
return dto;
})
.collect(toList());

第一种方法只需要对数据库进行一次查询,但由于返回的行数为 n * m,其中 n 是父表中的行数,m 是子表中的行数,因此数据量较高 table 。它还会在 java 方面产生 2(n * m) 的成本(一个用于分组,一个用于转换每一行)。

第二种方法会对数据库产生两次查询,但体积较小,因为返回的总行数为 n + m,并且每行都小于原始联接查询的每行。 java性能更好,因为它也是n + m(m用于分组子项,n用于处理和初始化父项)。

按照这个逻辑,我总是会选择选项二,但我对实际的 SQL 服务器没有很多实际经验。是否存在经验丰富的人会/应该选择选项 1 的情况?再次提交到数据库的成本是否会超过这些操作的复杂性差异?

最佳答案

如果您使用像 Hibernate 这样的 ORM 框架,这将在幕后自动处理。并且,它将使用第一个版本,其中联接发生在数据库上,而不是第二个版本。第一个版本更可取的原因是数据库被设计为非常有效地执行诸如连接之类的操作。 Java 在执行相同的连接操作时可能效率较低。我认为第二个版本可能更高效的唯一原因是数据往返数据库的延迟。第二个版本可能涉及传输较少的数据。但是,我认为在 Java 代码中执行数据库操作的惩罚会超过这个。

关于java - 性能二1 :N grouping methods,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51759711/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com