我有一个包含两个字段的简单实体
@Entity
@Table(name = "lctn_locations")
public class LocationEntity {
@Id
@Column(name = "id", updatable = false, nullable = false)
private UUID id;
@ElementCollection
@CollectionTable(
name = "lctn_location_devices",
joinColumns = @JoinColumn(name = "location_id", referencedColumnName = "id")
)
@Column(name = "device_id")
private Set<UUID> devices = new LinkedHashSet<>();
lctn_locations表包含780个条目。lctn_location_devices表仅包含11个条目。
我获取20个位置并将实体类转换为DTO,如下所示:
public Location map(LocationEntity locationEntity) {
Location location = new Location();
location.setId(locationEntity.getId());
long c2 = System.currentTimeMillis();
Set<UUID> devices = locationEntity.getDevices();
for(UUID deviceId : devices) {
location.getDevices().add(deviceId);
}
logger.info("Devices in {}ms", System.currentTimeMillis()-c2);
return location;
}
我的问题是每个位置的设备Map需要大约500毫秒。
将Entity上的devices字段设置为FetchType.EAGER并没有多大帮助,因为这样从DB的初始加载会比较慢。
lctn_location_devices有两个索引:
create index location_devices_location_id_device_id
on lctn_location_devices (location_id, device_id);
create index lctn_location_devices_location_id_index
on lctn_location_devices (location_id);
我对JPA的经验不够,我做错了什么吗?
1条答案
按热度按时间zbq4xfa01#
可以从记录应用程序发送到数据库的sql开始,方法是将以下内容添加到application.properties:
这不会给予您sql中的参数,但是您可以用相关的值替换sql中的
?
。然后,您可以尝试从数据库工具运行sql,看看它是否也很慢。
如果是这样,您可以尝试在数据库中运行解释计划。如何运行取决于您所使用的数据库。解释计划将为您提供一些有关sql中执行开销最高的部分的信息,并可能为您提供一些有关在何处优化代码的信息。
如果你想调查一下解释计划,你可以在youtube上给予一下解释计划。