我的spring boot应用程序在插入数据时性能非常慢。
我正在从一个数据库中提取大量数据,并将数据插入另一个数据库。
以下是我的实体。
@Entity
@Table(name = "element")
public class VXMLElementHistorical {
@Id
@Column(name = "elementid")
private long elementid;
@Column(name = "elementname")
private String elementname;
Getter/Setter methods...
我已经配置了一个JPA存储库
public interface ElementRepository extends JpaRepository<Element, Long> {
}
并使用我的对象调用Save()方法
@Transactional
public void processData(List<sElement> hostElements)
throws DataAccessException {
List<Element> elements = new ArrayList<Element>();
for (int i = 0; i < hostElements.size(); i++) {
Element element = new Element();
element.setElementid(hostElements.get(i).getElementid());
element.setElementname(hostElements.get(i).getElementname());
elements.add(element);
}
try{
elementRepository.save(elements);{
//catch etc...
}
目前的情况是,对于每个项目,执行插入操作需要6到12秒的时间。我打开了hibernate跟踪日志记录和统计功能,当我调用save函数时,hibernate执行两个查询,一个选择和一个插入。select查询占用了99%的总时间。
我直接在数据库上运行了select查询,结果以纳秒为单位返回。这让我相信这不是索引问题,但我不是DBA。
我已经在我的开发环境中创建了一个负载测试,在负载大小相似的情况下,整个过程的时间没有prod环境中的时间长。
有什么建议吗?
由于加载实体似乎是一个瓶颈,而且您真的只想进行插入,即您知道数据库中不存在实体,因此您可能不应该使用Spring Data JPA的标准save
方法。
原因是它执行合并
,触发Hibernate加载数据库中可能已经存在的实体。
相反,向存储库中添加一个自html" target="_blank">定义方法,该方法在实体管理器上执行持久化
。由于要预先设置Id
,请确保您有一个version属性,以便Hibernate可以确定这确实是一个新实体。
这将使选择消失。
其他答案中给出的其他建议值得作为第二步考虑:
合并
或持久化
实际上不会触发对数据库的写入,而只有刷新会(这是一个简化,但它应该适用于此上下文)正如@M. Deina在评论中所说,您可以通过在如下所示的一定数量的插入后调用flush()
和clear()
来改进。
int i = 0;
for(Element element: elements) {
dao.save(element);
if(++i % 20 == 0) {
dao.flushAndClear();
}
}
保存单个元素,而不是创建元素列表并保存这些元素。每隔一段时间,然后进行刷新
和清除
,以防止脏检查成为瓶颈。
@PersistenceContext
private EntityManager entityManager;
@Transactional
public void processData(List<sElement> hostElements)
throws DataAccessException {
for (int i = 0; i < hostElements.size(); i++) {
Element element = new Element();
element.setElementid(hostElements.get(i).getElementid());
element.setElementname(hostElements.get(i).getElementname());
elementRepository.save(element)
if ( (i % 50) == 0) {
entityManager.flush();
entityManager.clear();
}
}
entityManager.flush(); // flush the last records.
你想清除每个x元素(这里是50,但你可能想找到自己的最佳数字。
现在,当您使用Spring Boot时,您可能还想添加一些附加属性。比如配置批处理大小。
spring.jpa.properties.hibernate.jdbc.batch_size=50
如果您的JDBC驱动程序支持,这将把50条单insert语句转换成1条大批量insert语句。即50个插页到1个插页。
另见https://vladmihalcea.com/how-to-batch-insert-and-update-statements-with-hibernate/
我必须对Azure表存储进行查询,其中我有以下设置:RowKey、PartitionKey、ThirdColumn RowKey是唯一的,Partitionkey与ThirdColumn相关联,这意味着所有值为“Y”的第三列都将具有分区键“X”。 我必须使用ThirdColumn值获取分区键为X的所有实体。这将不是Performance,因为Y既不是PartitionKey也不是RowKey。 问
我有一个用例,需要以Json格式将调查结果从web应用程序上传到azure blob存储。根据调查问题判断,这些json对象将很小,甚至不会接近1MB。我一直在阅读C#中的azure blob客户端并进行实验。我实现了一个工作单元和存储库设计模式,这意味着每个CRUD操作都会导致与azure存储的连接。我是否应该考虑并行操作或批量调用以降低成本,提高性能和吞吐量?有很多关于并行操作的文章,但他们试
问题内容: 在MySQL中,性能和存储(空间)明智地归零是什么? 例如: TINYINT:1字节TINYINT w / NULL 1字节+以某种方式存储NULL? 问题答案: 这取决于您使用的存储引擎。 在MyISAM格式中,每个行标题都包含一个位域,每个列的每个位都具有一位以对NULL状态进行编码。NULL列仍会占用空间,因此NULL不会减少存储量。参见https://dev.mysql.com
本文向大家介绍阐述ArrayList、Vector、LinkedList的存储性能和特性相关面试题,主要包含被问及阐述ArrayList、Vector、LinkedList的存储性能和特性时的应答技巧和注意事项,需要的朋友参考一下 考察点:ArrayList ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,
我们在应用程序中使用ehcache。请看以下配置: 既然我们已经配置为eternal="true ",那么它会永远创建缓存吗?。磁盘空间有可能用完吗? 对磁盘存储的性能会有什么影响?。肯定比内存缓存慢,但是影响有多大。 如果磁盘中存储了更多缓存,是否会导致执行多个文件操作的IO问题? 请建议生产级应用的最佳实践。假设我们有一个3 GB的堆内存和25000个并发用户访问应用程序。但是,我们的应用程序
问题内容: 关于Spring JPA存储库事务性的1个快速问题。我有未标记为事务性的服务,并调用了Spring JPA存储库方法 它被定义为 问题是它失败,并且“ 没有EntityManager,当前线程没有可用的实际事务- 无法可靠地处理’remove’调用;嵌套异常是javax.persistence.TransactionRequiredException “异常。 好的,我可以通过将服务