# 先保持答案不變，再讓檢索更快

作者：Ian
發布：2026-10-06
更新：2026-10-06
實作紀錄期間：2026-09-30
正式網址：https://ianinfra.com/knowledge/rag-inverted-index/

當 RAG 查詢變慢，很容易直接想到換模型、加快向量搜尋，或再加一層排序。但在一次效能分析中，我先處理的是既有 lexical 比對：保持原本的計分方式，把逐片掃描改成倒排索引。

這一輪的目標很單純：先證明計算結果沒有變，再討論速度是否值得採用。

## 先固定比較的條件

我從資料庫備份取出 16,843 個活動片段，以同一份固定語料執行 60 題比較。舊版與新版使用相同的查詢與計分規則，核對的是每一題、每一個片段的分數，並非只看最終前幾名。

倒排索引讓查詢可以先找到相關詞對應的片段，減少不必要的逐片比對。這次沒有把加速與新的排序策略綁在一起，因此較容易判斷結果變化從何而來。

## 量到了什麼

| 比較項目 | 原版 | 倒排版 |
| --- | --- | --- |
| lexical 中位數 | 1,204.90 ms | 23.32 ms |
| lexical P95 | 1,304.10 ms | 32.29 ms |
| 60 題逐片分數 | 比較基準 | 全數等價，差異 0 |

在這份固定語料與題集上，lexical 中位數約減少 98%。這個數字只描述 lexical 階段，不能寫成「完整 RAG 問答快了 98%」。

另一組凍結題集跑實際產品檢索流程，前後都是 48/60。它說明既有缺口仍在，也提醒我：加速成功與召回品質改善，需要分開報告。

## 有些變更，總分相同仍然不採用

同一輪也比較了較大的向量候選數與 IDF 排序調整。

- 有效向量候選數從 40 增加到 80、120，題集結果都維持 48/60，因此保留較小的 40。
- IDF 改變了 16 題的來源順序，其中一題改善、另一題退步，總分仍為 48/60。
- 因為出現已知退化，IDF 保留為實驗功能，但正式設定關閉。

> 總分沒變，不代表原本能回答的問題都還答得出來。

逐題檢查的價值在這裡很明顯：平均數或總分可能把改善與退步抵銷，使用者遇到的卻是某一個具體問題。

## 加速也有成本與限制

這次倒排建表約需 2.40 秒。以 Python tracemalloc 量得索引配置約 346.53 MiB、建表峰值約 420.36 MiB；這不是整個服務的記憶體用量，也不包含所有原生配置。

正式環境另做了 34 題前後觀察，檢索中位數由 1,213 ms 降至 949 ms。不過期間索引仍在更新，前後版本不同，因此我把它列為現場觀察，不拿來當嚴格的同快照因果比較。

原始語料與逐題紀錄未公開。本文保留測試日期、樣本數、量測範圍與限制，數據代表該次實測，不能直接當成其他語料或硬體的效能預期。

## 下一步要重新看瓶頸

修正後的一筆限定範圍查詢中，lexical 已降到約 2 ms，主要時間轉到 embedding 與向量檢索。這時繼續優化 lexical，可能已不是最有價值的工作。

我會保留這個順序：固定資料與題目、確認結果等價、量測分段耗時、檢查逐題退化，再回到完整使用流程確認收益。

延伸閱讀：[RAG 變快了多少？先說清楚量的是哪一段。](/knowledge/rag-latency-evidence/)
