我最近遇到了一些JPA查询的性能问题,并开始研究解决它的方法。
我有以下命名查询:
<?php session_start();
require_once 'connect.php';
$a = 0;
$conn = @new mysqli($host, $dbuser,$dbpass,$dbname);
if ($conn->connect_errno!=0){
echo "Error ".$conn->connect_errno;
} else {
$id=$_SESSION["id"];
//echo 'to jest nasze id '.$id;
$sql = "SELECT * FROM zgloszenia WHERE user_id='$id'";
$wynik = $conn->query($sql);
echo '<table class="table table-striped">
<tr>
<th>id</th>
<th>stan</th>
<th>opis</th>
<th>data</th>
</tr>';
while($row = $wynik->fetch_assoc()) {
echo "<tr onclick='window.location='pagename.php?id= ".$row['id']."''>
<td>".$row['id']."</td>
<td>".$row['stan']."</td>
<td>".$row['opis']."</td>
<td>".$row['data_zgl']."</td>";
echo "</tr>";
$a++;
}
echo '</table>';
}
print_r($t);
$conn->close();
?>
然后我将其定时如下:
@NamedQuery(name = "EquipmentBooked.findAll", query = "SELECT e FROM EquipmentBooked e")
结果是:
String timings += "\nEquipmentBooked";
long startTime = System.currentTimeMillis();
List<EquipmentBooked> equipmentBookings = entityManager.createNamedQuery("EquipmentBooked.findAll", EquipmentBooked.class).getResultList();
timings += " - Query time [ms]: " + (System.currentTimeMillis() - startTime);
for(EquipmentBooked booking : equipmentBookings){
log.info(booking.getEquipmentBookedId());
}
timings += " - Total time [ms]: " + (System.currentTimeMillis() - startTime);
333秒仅约2000条记录!
然后我决定试一试本机查询:
EquipmentBooked - Query time [ms]: 333405 - Total time [ms]: 333460
这导致:
String timings += "\nEquipmentBooked (native)";
long startTime = System.currentTimeMillis();
List<EquipmentBooked> nativeEquipmentBooked = entityManager.createNativeQuery("select * from EQUIPMENT_BOOKED", EquipmentBooked.class).getResultList();
timings += " - Query time [ms]: " + (System.currentTimeMillis() - startTime);
for(EquipmentBooked booking : nativeEquipmentBooked){
log.info(booking.getEquipmentBookedId());
}
timings += " - Total time [ms]: " + (System.currentTimeMillis() - startTime);
6秒!好多了。
当我在同一个方法中运行这两个查询时,有趣的是,本机首先是命名查询。结果是:
EquipmentBooked (native) - Query time [ms]: 6607 - Total time [ms]: 6767
有人可以解释为什么本机查询速度更快,并提高了命名查询的性能吗?
注意:这些测试都是在任何实体被缓存并且数据库是Oracle之前运行的。
更新:删除了联接提取以确保查询相同。
更新2:在查看生成的SQL之后,我能看到的唯一区别如下:
EquipmentBooked (native) - Query time [ms]: 6607 - Total time [ms]: 6767
EquipmentBooked - Query time [ms]: 699 - Total time [ms]: 774
Vs以上。
SELECT EQUIPMENT_BOOKED_ID, CALENDAR_ENTRY_ID, EQUIPMENT_BOOKED_STATUS_ID, EQUIPMENT_ID, EXPERIMENT_PART_ID FROM EQUIPMENT_BOOKED
在这两种情况下,JPA驱动程序都会以相同的方式关闭并获取(许多)关系。 E.g:
select * from EQUIPMENT_BOOKED