專案需對千萬筆資料表進行插入/查詢操作。原以為輕鬆,實測發現傳統做法在百萬、千萬級別會遇到效能崩塌。經多方嘗試總結出以下關鍵經驗。
插入端:Hibernate 若用 Sequence 產生 ID,5 萬筆需 5 萬次資料庫往返取序號、5 萬次持久化,耗時 10 分鐘,瓶頸在取序號。改用 increment 雖解決但仍心有餘悸。
查詢端:Hibernate 面向物件查詢會載入大量不需要的關聯資料,佔用資料庫與記憶體資源。嘗試自訂 SQL、優化 HQL 均失敗,最終捨棄。
-- 差
SELECT * FROM x_table;
-- 優
SELECT id, name FROM x_table;
千萬筆資料下,單一欄位佔用的 I/O、網路、記憶體資源極其可觀。
前端傳遞查詢表單,後端解析時常用永真條件佔位:
-- 差:全表掃描 + LIKE '%' 無意義運算
SELECT COUNT(id) FROM x_table WHERE name LIKE '%';
-- 優:直接計數
SELECT COUNT(id) FROM x_table;
實測千萬筆:前者 33 秒,後者 11 秒,效能差 3 倍。
海量資料查詢盡量避免表聯結。若必須聯結,被聯結表資料量必須小。雙方均為萬筆級別時,查詢時間將超出使用者容忍度,應重新設計表結構(如冗余欄位、物化視圖、分表)。
多層 SELECT 巢狀時,在最內層就將結果集縮至最小(如先分頁再聯結),往往能帶來質的效能飛躍。將 ROWNUM 或分頁邏輯下推至最內層,避免外層處理海量中間結果。
海量資料操作核心原則:少傳輸、少運算、少聯結、早過濾。拋棄 ORM 便利性,回歸精簡 SQL,才是千萬級資料的生存之道。