Truy vấn khoảng cách nhanh hamming trong postgres


15

Tôi có một cơ sở dữ liệu lớn (16M hàng) chứa các hình ảnh băm nhận thức.

Tôi muốn có thể tìm kiếm các hàng bằng cách ham khoảng cách trong một khung thời gian hợp lý.

Hiện tại, theo như tôi hiểu đúng về vấn đề này, tôi nghĩ lựa chọn tốt nhất ở đây sẽ là triển khai SP-GiST tùy chỉnh thực hiện BK-Tree , nhưng có vẻ như rất nhiều công việc, và tôi vẫn còn mơ hồ về thực tế chi tiết thực hiện đúng một chỉ số tùy chỉnh. Tính khoảng cách Hamming là đủ dể làm, và tôi làm biết C, mặc dù.

Về cơ bản, cách tiếp cận phù hợp ở đây là gì? Tôi cần có thể truy vấn các kết quả khớp trong một khoảng cách chỉnh sửa nhất định của hàm băm. Theo tôi hiểu, khoảng cách Levenshtein với các chuỗi có độ dài bằng nhau là khoảng cách chức năng, do đó, có ít nhất một số hỗ trợ hiện có cho những gì tôi muốn, mặc dù không có cách rõ ràng nào để tạo chỉ mục từ đó (hãy nhớ, giá trị tôi đang truy vấn Tôi không thể tính toán trước khoảng cách từ một giá trị cố định, vì điều đó sẽ chỉ hữu ích cho một giá trị đó).

Các giá trị băm hiện được lưu trữ dưới dạng chuỗi 64 char chứa mã hóa nhị phân ASCII của hàm băm (ví dụ: "10010101 ..."), nhưng tôi có thể chuyển đổi chúng thành int64 đủ dễ dàng. Vấn đề thực sự là tôi cần có khả năng truy vấn tương đối nhanh.

Có vẻ như có thể đạt được điều gì đó theo những gì tôi muốn với pg_trgm, nhưng tôi không rõ về cách thức hoạt động của trigram phù hợp với hoạt động (cụ thể là, số liệu tương tự mà nó trả về thực sự đại diện cho cái gì? loại giống như khoảng cách chỉnh sửa).

Hiệu suất chèn không quan trọng (rất tốn kém về mặt tính toán để tính băm cho mỗi hàng), vì vậy tôi chủ yếu quan tâm đến việc tìm kiếm.


Tiện ích mở rộng smlar có thể có những gì bạn cần: pgcon.org/2012/schedule/attachments/252_smlar-2012.pdf hoặc pg_similarity: pgcon.org/2009/schedule/attachments/108_pg_similarity.pdf
Neil McGuigan

@NeilMcGuigan - Thú vị! Bài thuyết trình đầu tiên thực sự là từ những người duy trì hệ thống SP-GiST và GIST trong các postgres.
Tên giả

Liên kết đầu tiên là cho một cái gì đó về cơ bản khác nhau, mặc dù. họ đang tìm kiếm các giao lộ được thiết lập, trong khi tôi đang tìm kiếm khoảng cách. Tôi có thể sắp xếp các phash thành một tập hợp, nhưng nó sẽ cực kỳ lộn xộn và đòi hỏi rất nhiều mã hỗ trợ ở mọi nơi khác.
Tên giả

FWIW, Tại thời điểm này, tôi đã ít nhiều kết luận rằng tôi cần thực hiện hệ thống lập chỉ mục của riêng mình. Hiện tại tôi đang xem xét các chỉ số SP-GiST tùy chỉnh, nhưng tôi không biết mình đang làm gì.
Tên giả

1
@FakeName: Khi bạn nói khoảng cách hãm, tôi giả sử bạn có nghĩa là khoảng cách hãm của chuỗi giá trị băm, không phải hình ảnh? Nói cách khác, bạn đang muốn hỏi: Tìm tất cả các giá trị băm thay thế bit X khỏi tham số đầu vào
Thomas Kejser

Câu trả lời:


11

Chà, tôi đã dành một khoảng thời gian để xem việc viết một phần mở rộng C tùy chỉnh postgres, và chỉ cần viết một trình bao bọc cơ sở dữ liệu Cython duy trì cấu trúc cây BK trong bộ nhớ.

Về cơ bản, nó duy trì một bản sao trong bộ nhớ của các giá trị phash từ cơ sở dữ liệu và tất cả các bản cập nhật cho cơ sở dữ liệu được phát lại vào cây BK.

Tất cả đều ở trên github ở đây . Nó cũng có rất nhiều bài kiểm tra đơn vị.

Truy vấn trên bộ dữ liệu gồm 10 triệu giá trị băm cho các mục có khoảng cách 4 kết quả khi chạm ~ 0,25% -0,5% giá trị trong cây và mất ~ 100 ms.


BK-Tree trong bộ nhớ với 16 triệu hàng trong bộ nhớ? Tôi đã xem xét một cái gì đó tương tự tuy nhiên với 1000 hình ảnh và 2000 mô tả trên mỗi hình ảnh kích thước bộ nhớ của tôi là rất lớn.
Stewart

@Stewart - Rất nhiều thứ này phụ thuộc vào kích thước băm của bạn. Trong trường hợp của tôi, đầu ra giá trị băm là một bitfield 64 bit duy nhất mà tôi lưu trữ dưới dạng int64. Bạn dường như có một loại dữ liệu phash lớn hơn nhiều. Tôi cũng không chắc cách tìm kiếm sẽ hoạt động trên một kiểu dữ liệu khác như thế. Họ vẫn là một không gian số liệu? Làm thế nào để bạn tính toán khoảng cách?
Tên giả

Tôi đang sử dụng các mô tả 32 bit với trình biên dịch FLANN được cung cấp với opencv. Để tính khoảng cách, tôi sử dụng hamming với ngưỡng dựa trên tỷ lệ của Lowe. Tại thời điểm này, tôi không chắc có nên thử và gắn bó với bộ nhớ FLANN cung cấp cấu trúc cây KD hay để chuyển sang một giải pháp tương tự như của bạn. Tại sao cuối cùng bạn lại tự lăn lộn và không đi tìm thứ gì đó như libflann?
Stewart

@Stewart - Tôi không tự lăn. Tôi đang sử dụng băm dựa trên DFT siêu nhàm chán .
Tên giả

7

TRẢ LỜI NHẤT!

Ok, cuối cùng tôi đã dành thời gian để viết một phần mở rộng lập chỉ mục PostgreSQL tùy chỉnh. Tôi đã sử dụng giao diện SP-GiST .

Điều này khá khó khăn, chủ yếu là do Posgres rất lớn .

Dù sao, như thường lệ, nó ở trên github ở đây .

Hiệu suất khôn ngoan, hiện tại chậm hơn ~ 2-3 lần so với triển khai bộ nhớ thuần trong câu trả lời khác của tôi cho câu hỏi này, nhưng nó thuận tiện hơn nhiều khi sử dụng Tôi sẽ vui vẻ ăn hiệu suất đó (thực tế, nó ~ 50 ms / truy vấn - 150 ms / truy vấn, vẫn còn khá nhỏ).


Bạn thật tuyệt vời! Bạn có thể thêm README về cách cài đặt không? Tôi chưa bao giờ thực sự cài đặt bất cứ thứ gì trong Postgres: P
HypeWolf

1
@HypeWolf - Root của repo có README . Điều đó không bao gồm những gì bạn muốn?
Tên giả

Sai lầm của tôi, tôi đã không nhìn thấy nó, tôi không chắc là mình đang tìm kiếm ở đâu: /
HypeWolf

Đã tìm kiếm README là tốt. Nó nằm trong thư mục gốc. Các liên kết sẽ đi đến một số thư mục con. Điều đó thật khó hiểu.
luckydonald
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.