如何解决Spring Boot neo4j 性能
我们正在评估我们公司使用 neo4j 的可能性,我们使用 Java (>1.8)、Spring Boot (2.4.2) 和 SpringData-neo4j (2.4.2) 进行简单的查询和一些性能测试,neo4j 是使用官方 docker 镜像在 docker 容器中本地运行。
这是我们的设置:
json 结构
{
"id": null,"addresses": [
{
"id": null,"city": "South Thresa","country": "Burundi","houseNumber": "861","street": "Auer Lake","zipCode": "03412"
}
],"bankAccounts": [
{
"id": null,"bankAccountNumber": null,"bankName": null,"bic": "QVWPKO5H","blz": null,"countryCode": null,"divergentAccountHolder": null,"iban": "GB87DPZP84667918216002","sepaMandates": [
{
"id": null,"bankAccount": null,"signatureCity": "Lednerbury","signatureDate": "06.10.1984"
}
]
}
],"contacts": [
{
"id": null,"email": "tonisha.mitchell@gmail.com","faxNumber": "087-835-0885 x859","mobilePhoneNumber": "1-615-772-6922","phoneNumber": "(082) 785-8108 x6736"
}
],"birthDate": "07.01.1966","firstName": "Daniel","lastName": "Hartmann","salutation": "Mrs.","title": "Lead Branding Orchestrator"
}
实体:
@Node
public class Partner {
@Id
@GeneratedValue
public Long id;
@Relationship(type = "ADDRESS",direction = Relationship.Direction.INCOMING)
public List<Address> addresses;
@Relationship(type = "BANKACCOUNT",direction = Relationship.Direction.INCOMING)
public List<BankAccount> bankAccounts;
@Relationship(type = "CONTACTS",direction = Relationship.Direction.INCOMING)
public List<Contact> contacts;
@Property
public String birthDate;
@Property
public String firstName;
@Property
public String lastName;
@Property
public String salutation;
@Property
public String title;
}
@Node
public class Contact{
@Id
@GeneratedValue
public Long id;
@Property
public String email;
@Property
public String faxNumber;
@Property
public String mobilePhoneNumber;
@Property
public String phoneNumber;
@Node
public class BankAccount{
@Id
@GeneratedValue
public Long id;
@Property
public String bankAccountNumber;
@Property
public String bankName;
@Property
public String bic;
@Property
public String blz;
@Property
public String countryCode;
@Property
public String divergentAccountHolder;
@Property
public String iban;
@Relationship(type = "SEPA_MANDAT")
public List<SepaMandate> sepaMandates;
@Node
public class Address{
@Id
@GeneratedValue
public Long id;
@Property
public String city;
@Property
public String country;
@Property
public String houseNumber;
@Property
public String street;
@Property
public String zipCode;
@Node
public class SepaMandate{
@Id
@GeneratedValue
public Long id;
@Property
public BankAccount bankAccount;
@Property
public String signatureCity;
@Property
public String signatureDate;
存储库:
public interface PartnerRepository extends Neo4jRepository<Partner,Long> {
List<Partner> findByLastName(String name);
}
控制器有一个端点来触发大规模插入并停止时间
@PutMapping("/partner/initialInsert")
public void createPartner() {
List<Partner> partners = mockData();
StopWatch stopWatch = new StopWatch();
stopWatch.start();
partnerRepository.saveAll(partners);
stopWatch.stop();
System.err.println("Created: 100000 partnerEntries ---->>> Duration ------------> " + stopWatch.toString());
}
还有一些简单的查询/更新和插入端点
@GetMapping("/partner")
public List<Partner> getPartnerByLastName(@RequestParam(value = "lastname") String lastname) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
List<Partner> partners = partnerRepository.findByLastName(lastname);
stopWatch.stop();
System.err.println("Selecting partners by lastname: " +lastname + " took: " + stopWatch.toString() + " and returns: " + partners.size() + " partners");
return partners;
}
@PutMapping("/partner")
public void createPartner(@RequestBody Partner partner) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
partnerRepository.save(partner);
stopWatch.stop();
System.err.println("Updating/Inserting partner took: " + stopWatch.toString());
}
@PostMapping("/partner/bulk")
public void bulkUpdatePartner(@RequestBody List<Partner> partners) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
partnerRepository.saveAll(partners);
stopWatch.stop();
System.err.println("Updating/Inserting partner took: " + stopWatch.toString());
}
以下是我们的测试结果:
通过批量 saveAll() 插入随机数据。
- 已创建:1000 个合作伙伴条目 ---->> 持续时间 ------> 00:00:29.775
- 已创建:10000 个合作伙伴条目 ---->>> 持续时间 ------> 00:04:40.259
- 已创建:100000 个合作伙伴条目 ---->> 持续时间 ------> 00:53:48.862
多次通过姓氏选择数据
- 按姓氏选择合作伙伴:Borer 取:00:00:00.404 返回:257 个合作伙伴
- 按姓氏选择合作伙伴:Borer 取:00:00:00.219 返回:257 个合作伙伴
- 按姓氏选择合作伙伴:Borer 取:00:00:00.173 返回:257 个合作伙伴
- 按姓氏选择合作伙伴:Borer 取:00:00:00.239 返回:257 个合作伙伴
- 按姓氏选择合作伙伴:Borer 取:00:00:00.194 返回:257 个合作伙伴
- 按姓氏选择合作伙伴:Borer 获取:00:00:00.266 并返回:257 个合作伙伴
更新/插入单个条目:
- 更新合作伙伴时间:00:00:00.297
- 插入合作伙伴花了:00:00:00.124
使用 jpa 更新批量 256 个合作伙伴:
- 更新合作伙伴时间:00:00:08.931
使用不带 jpa 的会话对象更新批量 256 合作伙伴:
- 更新合作伙伴时间:00:00:00.090
我们真的很好奇使用 jpa 函数 saveAll() 进行批量插入需要 50 分钟以上的时间来插入 100.000 个对象,以及通过 jpa 和会话对象更新 256 个条目之间的差异。 现在的问题是,我们做错了什么,我们尝试使用没有任何特殊情况的简单设置,spring-data 集成有问题还是你们有类似的问题?我很期待你在 neo4j 方面的体验 :-)
问候丹:)
P.S:这就是我们更新会话对象的方式
try (Session session = driver.session()) {
session.run("MATCH (a:Partner {lastName: 'Borer'}) SET a.firstName = '" + firstname + "'");
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。