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
感謝葉老師的支持