9 điểm bởi GN⁺ 2025-11-04 | 5 bình luận | Chia sẻ qua WhatsApp
  • Phần mở rộng Postgres pgvector hỗ trợ tìm kiếm độ tương đồng vector, nhưng khoảng cách giữa mức demo và môi trường vận hành thực tế là rất lớn
  • Cả chỉ mục IVFFlat và HNSW đều có ưu và nhược điểm rõ rệt; đặc biệt HNSW gặp vấn đề về mức sử dụng bộ nhớ lên đến vài GB khi tạo chỉ mục và thời gian build dài
  • Tìm kiếm thời gian thực và cập nhật chỉ mục về mặt cấu trúc vốn đã khó, và khi chèn/cập nhật liên tục sẽ phát sinh tranh chấp khóa và suy giảm hiệu năng
  • Do chiến lược lọc (Pre/Post) và giới hạn của query planner, sẽ xuất hiện sự cân bằng thiếu ổn định giữa độ chính xác tìm kiếm và tốc độ
  • Các chức năng do cơ sở dữ liệu vector chuyên dụng (Pinecone, Weaviate, v.v.) cung cấp phải được tự triển khai thủ công, và kết quả là độ phức tạp vận hành cùng chi phí tăng lên

Tổng quan về các giới hạn của pgvector

  • pgvector là một extension bổ sung khả năng tìm kiếm độ tương đồng vector cho Postgres; nó hoạt động tốt trong các demo đơn giản nhưng gặp vấn đề về khả năng mở rộng trong môi trường vận hành
  • Nhiều bài blog chỉ đề cập đến cài đặt và ví dụ truy vấn đơn giản, còn các vấn đề về hiệu năng, bộ nhớ và quản lý chỉ mục khi vận hành thì hầu như không được nhắc tới

Vấn đề trong việc lựa chọn chỉ mục

  • pgvector cung cấp hai loại chỉ mục là IVFFlatHNSW
    • IVFFlat: cấu trúc dựa trên cụm, tốc độ tạo chỉ mục nhanh nhưng việc thiết lập số lượng cụm ảnh hưởng lớn đến hiệu năng và độ chính xác
      • Không thể tái phân bổ cụm nên cần tái dựng chỉ mục định kỳ
    • HNSW: cấu trúc đồ thị nhiều lớp, mang lại độ chính xác và hiệu năng ổn định nhưng mức sử dụng bộ nhớ khi tạo chỉ mục rất cao và tốc độ chậm
  • Khi tạo chỉ mục cho hàng triệu vector, có thể cần hơn 10GB RAM, đây là mối đe dọa trực tiếp đến độ ổn định của DB đang vận hành

Khó khăn của tìm kiếm thời gian thực

  • Dữ liệu mới cần phải có thể được tìm kiếm ngay sau khi chèn, nhưng do cấu trúc cập nhật chỉ mục nên rất khó phản ánh theo thời gian thực
    • IVFFlat: vector mới được thêm vào cụm hiện có, theo thời gian sẽ phát sinh mất cân bằng cụm → cần rebuild định kỳ
    • HNSW: khi chèn sẽ cập nhật đồ thị, gây ra tranh chấp khóa và tải bộ nhớ
  • Trong quá trình tái dựng chỉ mục, rất khó duy trì tính nhất quán dữ liệu và đảm bảo tính liên tục của dịch vụ
  • Trong môi trường vận hành, cần nhiều chiến lược lách vấn đề như staging table, chỉ mục kép, build offline, eventual consistency

Giới hạn của lọc và query planner

  • Khi kết hợp lọc metadata như status, user_id, category với tìm kiếm vector, việc chọn Pre-filter hay Post-filter ảnh hưởng lớn đến hiệu năng
    • Pre-filter phù hợp với bộ lọc có tính chọn lọc cao, nhưng sẽ chậm khi dữ liệu lớn
    • Post-filter nhanh hơn nhưng có khả năng bỏ sót kết quả sau khi lọc
  • Query planner của Postgres không hiểu mô hình chi phí của độ tương đồng vector, thông tin thống kê không chính xác nên tạo ra kế hoạch thực thi kém hiệu quả
  • Kết quả là cần các giải pháp tạm thời như CTE, partitioning, viết lại truy vấn, và điều này kém hiệu quả khi mở rộng quy mô

So sánh với cơ sở dữ liệu vector chuyên dụng

  • Pinecone, Weaviate, OpenSearch k-NN, v.v. mặc định cung cấp tự động chọn chiến lược lọc, tìm kiếm hybrid, indexing thời gian thực, mở rộng theo chiều ngang
  • Trong pgvector, các chức năng này phải tự triển khai, dẫn đến độ phức tạp vận hành và gánh nặng bảo trì
  • pgvectorscale của Timescale cung cấp StreamingDiskANN, build chỉ mục tăng dần, cải thiện lọc, v.v., nhưng
    • không được hỗ trợ trên AWS RDS và vẫn tồn tại gánh nặng cài đặt, quản lý extension bổ sung

Chi phí và các cân nhắc vận hành

  • Cơ sở dữ liệu vector chuyên dụng là dịch vụ trả phí, nhưng nếu tính đến việc overprovision hạ tầng Postgres, quản lý chỉ mục và thời gian kỹ sư, thì trên thực tế có thể rẻ hơn
  • Ví dụ, Turbopuffer bắt đầu từ $64/tháng và mang lại sự đơn giản trong vận hành cùng khả năng mở rộng

Kết luận và khuyến nghị

  • pgvector rất xuất sắc về mặt kỹ thuật nhưng có nhiều ràng buộc trong môi trường vận hành
  • Những điểm cốt lõi cần cân nhắc khi xây dựng hệ thống vận hành
    1. Độ phức tạp của quản lý chỉ mục và nhu cầu bộ nhớ cao
    2. Giới hạn của query planner dẫn đến lọc kém hiệu quả
    3. Chi phí của indexing thời gian thực và sự suy giảm chất lượng
    4. Sự đơn giản hóa quá mức trong các tài liệu blog
    5. Lý do tồn tại của cơ sở dữ liệu vector chuyên dụng và hiệu quả của chúng
  • Kết luận lại, độ phức tạp vận hành lớn hơn sự đơn giản của việc tích hợp với Postgres, và với phần lớn đội ngũ, sử dụng cơ sở dữ liệu vector chuyên dụng là lựa chọn thực tế hơn

5 bình luận

 
kaydash 2025-11-05

Dù vậy, với truy vấn kết hợp (embedding + SQL truyền thống) thì vẫn không gì bằng pg_vector.

 
yangeok 2025-11-04

Tôi nghĩ rằng để hệ sinh thái trở nên lành mạnh hơn thì cũng cần có nhiều ý kiến phản biện đối với những lời tung hô vạn năng.

 
ethanhur 2025-11-05

Tôi đồng ý. Với các tổ chức vốn đã dùng Postgres tốt từ trước và bắt đầu VectorDB với lượng dữ liệu nhỏ, pgVector rõ ràng là một lựa chọn rất tốt, nhưng khi lưu lượng truy cập tăng lên, đặc biệt là write traffic, thì có vẻ những vấn đề mà tác giả bài gốc nêu ra sẽ trở thành nút thắt cổ chai.

 
ndrgrd 2025-11-04

Đúng vậy. Vì không có gì là hoàn hảo cả. Tôi nghĩ có thể chấp nhận kiểu nói như “còn có việc cấp bách khác”, nhưng không nên chấp nhận “mức hiện tại cũng đã đủ rồi”.

 
GN⁺ 2025-11-04
Ý kiến trên Hacker News
  • Chúng tôi tại Discourse đã dùng pgvector trong môi trường production trên hàng nghìn cơ sở dữ liệu
    Nó được dùng cho phần lớn pageview, và tính năng Iterative Scans được thêm từ phiên bản 0.8.0 để cải thiện các vấn đề lọc trước/sau
    Với một dịch vụ đơn lẻ thì vector DB chuyên dụng có thể dễ hơn, nhưng đó không phải là lời giải vạn năng

    • Chúng tôi dùng quantization rất tích cực
      Dùng halfvec (float 16 bit) để lưu trữ, và bit (binary vectors) cho index để vừa tối ưu chi phí lưu trữ vừa đảm bảo hiệu năng
    • Ở công ty Halcyon của chúng tôi, chúng tôi xử lý hàng nghìn tỷ embedding, và Postgres không phù hợp ở quy mô đó
      Chúng tôi dùng Vespa để thực hiện tìm kiếm kiểu map-reduce ở cấp node
      Để làm điều tương tự với Postgres có lẽ sẽ cần sharding và logic ứng dụng phức tạp
      Việc reindex hoặc phi chuẩn hóa metadata có lẽ sẽ luôn mất nhiều thời gian
      Dù vậy vector DB cũng không phải vạn năng, và những hệ thống hỗ trợ lọc quan hệ như Vespa hiệu quả hơn nhiều
    • Có nhiều người dùng pgvector trong production
      Nhưng iterative scan không phải giải pháp căn cơ mà gần với biện pháp tạm thời hơn
      Cần hiểu các tham số như ef_search, max_search_tuples, và planner không thực sự hiểu đầy đủ cost model của tìm kiếm vector có lọc
      Cuối cùng đây là chuyện bạn có đủ khả năng tinh chỉnh query planner thông minh hay sẽ dùng một dịch vụ chuyên xử lý việc đó
    • Cũng có cách tiếp cận thực hiện lọc ngay trong quá trình duyệt index
      Phương pháp được mô tả trong bài báo của Microsoft đã được Timescale triển khai trong pgvectorscale
      Cách này có thể hiệu quả hơn lọc trước/sau đơn thuần
    • Tôi tò mò nó được dùng cho mục đích gì. Có phải là hệ thống tìm kiếm lai kết hợp từ khóa + vector không?
  • Chúng tôi ở VectorChord đã giải quyết hầu hết các vấn đề của pgvector được nhắc trong bài blog
    Dùng IVF + quantization để hỗ trợ cập nhật nhanh hơn 15 lần so với HNSW của pgvector
    Với 16 vCPU, 32GB bộ nhớ có thể index 100 triệu vector 768 chiều trong 20 phút
    Có thể reindex mà không mất dữ liệu bằng CREATE INDEX CONCURRENTLY
    Cũng hỗ trợ lọc trước/sau và tìm kiếm lai dựa trên BM25
    Xem thêm tại blog VectorChord

    • Tôi tò mò chỉ số recall thực tế là bao nhiêu nếu dùng quantization và IVF
    • Chúng tôi có khách hàng đang vận hành 3 tỷ vector bằng Postgres + VectorChord + sharding
      Có thể xem trường hợp liên quan trong blog này
    • Tôi đã xem xét VectorChord nhưng không được hỗ trợ trên RDS, nên phải thêm một dịch vụ riêng và vì thế không thể áp dụng
  • Việc build index dùng nhiều bộ nhớ, nhưng có thể kiểm soát bằng maintenance_work_mem
    Việc rebuild index có thể xử lý bằng REINDEX CONCURRENTLY, và cập nhật HNSW về mặt khái niệm tương tự như cập nhật B+tree
    Bài này cho cảm giác như tác giả chưa đọc kỹ tài liệu Postgres

    • Nhưng nếu giới hạn maintenance_work_mem thì việc index sẽ chậm hơn
      B+tree chỉ đụng tới log H page, còn HNSW phải sửa hàng nghìn vector
    • Index HNSW có thể lớn từ hàng trăm GB đến hàng TB
      Để rebuild nó, bạn phải chuẩn bị dung lượng DB hơn gấp đôi, và nó cũng ảnh hưởng đến các workload khác
      REINDEX CONCURRENTLY cũng mất nhiều thời gian
      Dù độ phức tạp chèn HNSW thấp, chi phí hằng số của nó lớn nên trên thực tế vẫn là gánh nặng
    • Dù có các thiết lập như maintenance_work_mem, việc chiếm RAM cỡ GB trong nhiều giờ khi đang vận hành là rất rủi ro
      REINDEX CONCURRENTLY cũng dùng thêm 2–3 lần dung lượng đĩa và ảnh hưởng hiệu năng
      Cuối cùng vấn đề không phải là Postgres thiếu tính năng, mà là độ phức tạp vận hành rất cao
      Vector DB chuyên dụng tự động xử lý những việc này, nên với các team nhỏ sẽ hiệu quả hơn nhiều
  • Việc Turbopuffer có giá khởi điểm từ 64 USD/tháng giải thích vì sao pgvector lại phổ biến
    Nếu 64 USD nghe đắt thì dùng pgvector, còn nếu thấy rẻ thì có lẽ use case của bạn đã đủ phức tạp để vector DB chuyên dụng phù hợp hơn

  • Tôi đã thấy khá nhiều khách hàng GCP dùng pgvector HNSW trong production
    Nhưng thực tế chỉ khả thi ở quy mô từ 0 đến 10 triệu vector
    Cần tính đến ETL, overhead vận hành, các vấn đề nhất quán, v.v.
    Nếu cần transaction, tìm kiếm lai và độ trễ thấp thì AlloyDB + ScaNN là lựa chọn tốt hơn
    (Để tham khảo thì tôi từng tạo ra ScaNN ở GCP và hiện đang dẫn dắt AlloyDB Semantic Search)

    • AlloyDB không phải mã nguồn mở, nên đó là sản phẩm nhắm đến một thị trường khác
  • Nguyên tắc mặc định của tôi là YAGNI
    Giảm số lượng dịch vụ xuống mức thấp nhất có thể, và chỉ thêm cái mới khi thật sự gặp vấn đề
    Nếu Postgres là đủ thì cứ dùng, còn nếu không thì lúc đó bạn sẽ biết chính xác mình cần gì

    • Nhưng cách tiếp cận này thường phản tác dụng
      Những thứ như ghi vector thời gian thực, kết hợp bộ lọc SQL với tìm kiếm tương đồng nghe có vẻ nhỏ nhặt nhưng thực tế là tính năng thiết yếu
      Khi quy mô tăng lên, những ràng buộc này sẽ bộc lộ thành vấn đề chí mạng
    • Vì cơ sở dữ liệu một khi đã chọn thì rất khó thay thế, nên ngay từ đầu phải cẩn trọng
  • Khi dùng mô hình vector embedding, nó rất hữu ích ngay cả khi không có dataset quy mô lớn
    Ví dụ như tìm kiếm tài liệu hay tìm kiếm thông tin sản phẩm
    Tôi muốn một giao diện kiểu file system, nơi khi ghi tài liệu vào thì index được cập nhật tự động
    Vì vậy những dịch vụ như Amazon S3 Vectors(liên kết) rất đáng chú ý
    Tôi tò mò về trải nghiệm sử dụng thực tế

    • Bạn đã thử cocoindex chưa?
      Có thể tham khảo tutorial liên quan trong bài này
  • Những vấn đề được nhắc tới thực ra đã được giải quyết, và tôi thích dùng PGVector hơn
    Nếu Postgres có thể thay Kafka để xử lý 100.000 sự kiện mỗi giây, thì PGVector cũng hoàn toàn có thể thay các vector DB chuyên dụng như Chroma
    Liên kết tham khảo

    • Tôi muốn biết cụ thể những vấn đề nào đã được giải quyết
  • Hầu hết các use case của pgvector là dataset nhỏ kiểu “chatbot dựa trên tài liệu kỹ thuật
    Dữ liệu không thay đổi thường xuyên, không có multi-tenancy nên vấn đề lọc cũng ít hơn
    Trong khi đó Chroma hỗ trợ SPANN, SPFresh, tìm kiếm lai, và là mã nguồn mở Apache 2.0 hoàn chỉnh
    Với mô hình tính phí theo mức sử dụng, chi phí cũng có thể chỉ khoảng 1 USD/tháng

  • Redis Vector Sets mà tôi phát triển suốt 1 năm qua giải quyết các vấn đề này
    Nó tự triển khai HNSW nên hỗ trợ cập nhật thời gian thực, và khi xóa thì bộ nhớ cũng được thu hồi ngay
    Hỗ trợ tốc độ chèn hàng trăm nghìn ops/giây, tìm kiếm 50.000 ops/giây
    Mặc định hỗ trợ quantization nên cũng rất hiệu quả về bộ nhớ
    Mọi thứ được trình bày chi tiết trong tài liệu README
    Hiện tại tính năng replication cũng đã được kiểm thử hoàn chỉnh