向量數據庫技術內核:從存儲到檢索,拆解其高效運作的秘密

寫在前面:我也是“被向量數據庫名詞轟炸”過的人
説實話,我第一次接觸向量數據庫的時候,是有點抗拒的。
那會兒各種文章都在説:
- 向量數據庫是 AI 時代的“新型基礎設施”
- 沒有向量數據庫,大模型就跑不起來
- 它徹底改變了傳統數據庫的範式
結果我真正打開文檔一看,全是:
- embedding
- ANN
- IVF
- HNSW
- PQ
名詞密度高到讓我一度懷疑:
這是不是又一個“包裝得很厲害的老技術”?
直到後來我在項目裏真的開始用它、調它、踩坑、看源碼,才慢慢意識到一件事:
向量數據庫真正有價值的地方,不在概念,而在它對「存儲 + 檢索」這件事做了極其激進的工程優化。
這篇文章,我不打算從“是什麼”講起,而是想換個更工程化的視角:
一個向量,從進數據庫到被檢索出來,中間到底經歷了什麼?
一切的起點:為什麼“向量”這件事,本身就很麻煩
在傳統數據庫裏,我們處理的是:
- int
- string
- datetime
- 少量結構化字段
它們的共同特點是:
可比較、可排序、可精確匹配。
而向量完全不是這麼回事。
一個 embedding,通常是:
- 384 / 768 / 1536 維
- float32 或 float16
- 本身沒有任何“語義”,只是一個數值數組
你沒法説:
這個向量 = 那個向量
你只能説:
這兩個向量,有多像
而“有多像”,通常意味着:
- 餘弦相似度
- 內積
- 歐式距離
到這裏,其實問題已經很清楚了。
向量數據庫的本質問題只有一個:
如何在“巨量高維浮點向量”中,快速找到“足夠相似”的那幾個?
注意我用的是“足夠相似”,而不是“最相似”。
這個細節,後面會反覆出現。
向量存儲:真的只是把 float 存起來嗎?
剛開始我也以為,向量數據庫的“存儲”階段應該很簡單:
不就是一堆 float 數組寫到磁盤上嗎?
後來才發現,這個想法太天真了。
存儲的第一個難題:空間
假設你有:
- 1000 萬條向量
- 每條 768 維
- float32
那光原始數據就是:
1000萬 × 768 × 4 bytes ≈ 30GB
這還沒算索引、元數據、緩存。
所以第一個現實問題就是:
向量數據庫不可能只存“原始向量”。
壓縮,是繞不開的第一步
幾乎所有成熟的向量數據庫,都會在某個階段引入向量壓縮。
但這裏有一個經常被忽略的點:
向量壓縮不是為了省錢,而是為了“讓檢索跑得動”。
常見思路包括:
- 降低精度(float32 → float16 / int8)
- Product Quantization(PQ)
- Scalar Quantization
它們的共同目標只有一個:
用更少的 bit,保留“相對距離關係”。
這也是為什麼你會看到很多向量數據庫文檔裏反覆強調一句話:
壓縮後,相似度計算仍然“足夠準確”。
這裏的“足夠”,非常工程化。
真正的核心:為什麼不能暴力算相似度?

「全量暴力搜索 vs ANN 搜索」複雜度對比圖
如果你向量數量很少,事情其實很簡單。
比如 1 萬條向量,你完全可以:
- 對 query 向量
- 和所有向量
- 全量算一遍相似度
- 排序取 topK
但問題是,真實世界裏幾乎沒人這麼玩。
一旦數據量上來,全量計算就直接不可接受了。
這也是向量數據庫真正開始和傳統數據庫分道揚鑣的地方。
ANN:向量數據庫繞不開的“不完美選擇”
説句實話,如果你追求的是絕對精確,那向量數據庫本身就是錯的。
因為它幾乎都建立在一個前提之上:
我不追求最優解,我追求一個足夠好的近似解。
這就是所謂的 ANN(Approximate Nearest Neighbor)。
我當時第一次意識到這一點的時候,其實挺震驚的。
因為這意味着:
- 向量數據庫從設計之初
- 就放棄了“絕對正確”
換來的,是速度和可擴展性。
從工程角度理解:索引到底在幹什麼?

“全部向量” → “候選集” → “TopK”
如果你把向量數據庫當成一個黑盒,很容易迷失在各種算法名詞裏。
但如果換個角度想:
索引的核心目的,其實只有一個:
儘可能少地看向量,但還能找到差不多對的那幾個。
所有 ANN 索引,本質上都在做這件事。
以 HNSW 為例:為什麼“圖”這麼好用?
HNSW 是我個人覺得最“反直覺但又最工程化”的一種索引結構。
它不是樹,也不是 hash,而是一張圖。
更準確地説,是多層小世界圖。
你可以這樣理解它:
- 每個向量是一個點
- 相似的向量之間連邊
- 上層圖稀疏、下層圖密集
搜索的時候:
- 從上層快速跳躍
- 慢慢下沉
- 最後在底層精細搜索
這裏面有個很重要的工程思想:
先用很便宜的計算,縮小搜索範圍;
再用更貴的計算,做精細判斷。
為什麼向量檢索速度能這麼快?
這個問題我後來想了很久,最後得出的結論其實很樸素:
向量數據庫快,不是因為算得快,而是因為算得少。
它通過:
- 索引結構
- 壓縮表示
- 分層搜索
把原本“必須算 1000 萬次”的事情,變成:
只算幾千次,甚至幾百次。
哪怕每次計算稍微複雜一點,整體還是賺的。
再説一個經常被忽略的點:內存結構

「內存 / 緩存 / 磁盤」分層訪問示意圖
很多人會以為,向量數據庫主要瓶頸在 CPU。
但在真實系統裏,內存佈局和緩存命中率反而非常關鍵。
一些非常工程但很少被寫進文章的事實:
- 向量通常會被按塊存儲,方便 SIMD
- 熱向量和索引節點會盡量常駐內存
- IO 只在必要時發生
這也是為什麼很多向量數據庫會強調:
內存越大,體驗越好
不是營銷,是事實。
從存儲到檢索,一次完整請求發生了什麼?
我們把流程串起來看一次。
當你發起一次向量檢索請求時,大致會發生:
- query 被轉成 embedding
- embedding 被歸一化
- 從索引結構中選出候選集合
- 對候選向量做精細相似度計算
- 排序、返回 topK
- 如果有 metadata filter,再做一次過濾
注意一個細節:
真正算“精確相似度”的向量,數量其實很少。
這就是整個系統能跑起來的關鍵。
為什麼向量數據庫和“傳統數據庫 + 插件”不一樣?
我一開始也嘗試過:
能不能在 MySQL / PostgreSQL 裏直接存向量?
答案是:
能,但體驗非常差。
原因並不複雜:
- 存儲層不是為高維 float 優化的
- 緩存策略不合適
- 沒有針對 ANN 的索引結構
向量數據庫並不是“多了個字段類型”,
而是從存儲到檢索路徑全部重新設計過的一套系統。
寫到這裏,説點更現實的
如果你只是:
- 數據量不大
- QPS 很低
- 對延遲不敏感
你未必真的需要一套完整的向量數據庫。
但一旦你遇到:
- 向量規模上百萬
- 檢索要進主流程
- 延遲必須穩定
那你會非常清楚地感受到:
這些“看起來很複雜的設計”,
本質上都是被工程現實逼出來的。
最後:我現在怎麼看向量數據庫
如果讓我用一句話總結向量數據庫,我會説:
它不是一項“新技術”,而是一堆老思想在 AI 場景下的極限工程化。
- 高維數據
- 近似搜索
- 空間換時間
- 不追求完美,只追求可用
這些思想其實並不新,但在大模型時代,被推到了一個前所未有的規模。
如果你已經開始在真實項目裏用向量數據庫,大概率會遇到一個現實問題:
理論都懂了,但怎麼把向量、檢索、模型訓練這幾件事真正連起來,反而更麻煩。
尤其是在做 RAG 或大模型應用時,向量數據庫往往只是鏈路中的一環,前後還牽扯到:
- embedding 模型選擇
-數據構建與清洗
-檢索效果評估
-以及後續的模型微調與對齊
在這種情況下,很多團隊會選擇先用一些已經把訓練和工程流程封裝好的工具,把整體鏈路跑順,再逐步替換成更定製化的方案。
比如像 LLaMA-Factory online這樣的工具,已經把模型微調、數據處理、實驗配置這些容易出錯的工程細節做了封裝,對於想快速驗證思路、減少重複造輪子的團隊來説,會是一個相對省心的起點。
它解決的不是“算法更先進”,而是一個很現實的問題:
讓工程師把精力放在真正需要思考的地方,而不是反覆踩同樣的工程坑。