在 Elasticsearch 里,“昂貴”并不單指“CPU 時間”,而是綜合了 **CPU、內存、磁盤 I/O、網絡傳輸** 以及 **實現復雜度** 的代價。下面把常見“昂貴算法”拆開說:
1. **高計算密度的文本算法** ?
? **match_phrase + slop**(帶跨距的短語) ?
? **span_near / span_first / span_or**(跨度查詢) ?
? **script_score** 自己寫 Groovy/Painless(循環、數學函數、外部字段) ?
代價:每條文檔都要跑正則、循環或復雜數學,CPU 飆升。
2. **向量/距離計算** ?
? **dense_vector + cosineSimilarity / dotProduct** ?
? **knn search + 向量量化再打分** ?
代價:一次向量運算 O(D)(D=維度),高維(512/1024) 再乘以 window_size=500 就十幾萬浮點乘法。
3. **機器學習/學習排序 (LTR)** ?
? **rank_feature + xgboost 模型** ?
? **自定義 feature、pair-wise loss** ?
代價:每條文檔要提取幾十上百個特征 → 內存抖動 + JNI 調用。
4. **跨字段或跨索引 Join** ?
? **has_child / has_parent / nested** 多層查詢 ?
? **terms lookup** 從另一索引拉百萬 ID 列表 ?
代價:大量隨機磁盤讀 + 網絡序列化。
5. **大窗口二次腳本** ?
把 window_size 調到 5 000 甚至 50 000,再跑上述任意算法,延遲直接秒級起步。
---
一句話判斷“貴不貴”: ?
**只要該算法在單條文檔上的耗時 > 一次普通 BM25 match 的 5~10 倍,或需要額外內存/磁盤隨機讀,就可以稱為“昂貴的算法”**——放到 rescore 里,只對 Top-N 跑,能把整體成本從 O(total_docs) 降到 O(window_size)。
一句話: ?
**“不昂貴的算法” ≈ 只用倒排索引、不走復雜計算、不隨機磁盤讀、不額外占內存的查詢——典型就是最簡單的 BM25/TF-IDF 關鍵詞匹配。**
具體看 Elasticsearch 里的“便宜”操作:
| 類型 | 例子 | 便宜原因 |
|---|---|---|
| **Term 級查詢** | `term`, `terms`, `range`(數值/日期) | 直接查倒排列表,O(log N) 跳表 |
| **Match 查詢** | `match` 默認 BM25 | 純倒排 + 預計算 norm,無額外 CPU |
| **Filter 子句** | `bool.filter` | 只算位圖交集,**不計分、可緩存** |
| **常量打分** | `constant_score` | 直接給固定 1.0 分,不走 BM25 |
| **小結果集聚合** | `terms` / `date_histogram` 結果 < 幾萬 | 位圖遍歷在內存完成 |
對照“昂貴”算法(向量、腳本、嵌套、跨字段 join…),它們要么 **逐條做復雜計算**,要么 **隨機磁盤讀**,要么 **內存膨脹**;而上面這些“便宜”操作幾乎只靠 **倒排索引 + 位圖/跳表**,CPU 和內存開銷都極低。