1.对象关系如下:
2.三张表数据量为:
potato_storehouse_InventoryChange 7万+
potato_sales_BILLOFLADING 2万+
potato_sales_BILLOFLADINGITEM 3万+
3.原始jpql如下:
select st from InventoryOut st where st.deleted=false
order by st.changeNo desc,st.billOfLadingItem.billOfLading.billOfLoadingNo desc
4.自动生成的sql如下:
SELECT
a.*
FROM
potato_storehouse_InventoryChange a
CROSS JOIN potato_sales_BILLOFLADINGITEM c
CROSS JOIN potato_sales_BILLOFLADING b
WHERE
a.billOfLadingItemId = c.id
AND c.BILLOFLADINGID = b.id
AND a.deleted = 0
order by a.changeNo desc,b.billOfLoadingNo desc limit 20
该有的索引都是正常的,但是我本机(开发笔记本中低配置)基本卡死不动。服务器是磁盘阵列,16G内存勉强能运行。
5.优化
经过分析,这个sql是用户默认进入界面产生的查询,这个查询使用了全表扫描并且海量笛卡尔积再处理,导致消耗大量I/O、内存。如果把提单号排序作为第二条件,业务上没有意义。因为已经根据出库单号降序了,再根据提单号排序就没有必要了。去掉提单号排序后,性能明显提升。生成的sql如下:
select inventoryo0_.* from potato_storehouse_InventoryChange inventoryo0_ where
inventoryo0_.DISCRIMINATOR='INVENTORYOUT' and inventoryo0_.deleted=0 order by a.changeNo desc limit 20
感谢叶老师的支持