postgres의 빠른 해밍 거리 쿼리


15

지각 해시 이미지를 포함하는 큰 데이터베이스 (16M 행)가 있습니다.

합리적인 시간 내에 해밍 거리 로 행을 검색하고 싶습니다 .

현재 문제를 올바르게 이해하는 한 여기에서 가장 좋은 옵션은 BK-Tree 를 구현하는 사용자 지정 SP-GiST 구현 이라고 생각하지만 많은 작업처럼 보이며 여전히 실용적입니다. 맞춤 색인을 올바르게 구현하는 데 대한 세부 정보 해밍 거리를 계산하는 것은 다루기 쉬운 충분하다, 나는 할 수 있지만, C를 알고있다.

기본적으로 여기에 적절한 접근 방법은 무엇입니까? 해시의 특정 편집 거리 내에서 일치 항목을 쿼리 할 수 ​​있어야합니다. 내가 알고있는 것처럼, 같은 길이의 문자열 Levenshtein 거리가 기능적으로 거리를 해밍, 그래서 적어도이 몇 가지 내가 원하는에 대한 기존 지원은 (기억에서 명확한 방법은, 내가를 쿼리하고있어 값을 인덱스를 생성하지 않으려면하지만, 고정 값으로부터의 거리를 미리 계산할 수는 없습니다. 그 값은 해당 값에만 유용하기 때문입니다).

해시는 현재 해시의 이진 ASCII 인코딩 (예 : "10010101 ...")을 포함하는 64 자 문자열로 저장되지만 쉽게 int64로 변환 할 수 있습니다. 실제 문제는 상대적으로 빠른 쿼리가 가능해야한다는 것입니다.

내가 원하는 것의 선을 따라 무언가를 달성하는 것이 가능할 수있는 것처럼 보이지만 pg_trgmtrigram match mechamism이 어떻게 작동하는지 (특히, 반환되는 유사성 메트릭이 실제로 무엇을 나타내는 지) 약간 불분명합니다. 편집 거리와 같은 종류).

삽입 성능은 중요하지 않습니다 (각 행의 해시를 계산하는 데 계산 비용이 많이 듭니다). 나는 주로 검색에 관심이 있습니다.



@NeilMcGuigan-재미있는! 첫 번째 프레젠테이션은 실제로 postgres에서 SP-GiST 및 GIST 시스템을 유지 관리하는 사람들이 발표 한 것입니다.
가짜 이름

첫 번째 링크는 근본적으로 다른 것입니다. 그들은 교차점을 찾고 있지만 해밍 거리를 찾고 있습니다. 파시를 세트에 집어 넣을 수는 있지만 매우 지저분하고 다른 곳에서는 많은 지원 코드가 필요합니다.
가짜 이름

FWIW,이 시점에서 필자는 자체 인덱싱 시스템을 구현해야한다고 결론을 내 렸습니다. 나는 현재 맞춤 SP-GiST 지수를 조사하고 있지만, 내가 무엇을하고 있는지 전혀 모른다.
가짜 이름

1
@ 가짜 이름 : 해밍 거리를 말할 때 이미지가 아닌 해시 값 문자열의 해밍 거리를 의미한다고 가정합니다. 다시 말해, 당신은 묻고 자합니다 : 입력 매개 변수에서 X 비트로 대체되는 모든 해시 값을 찾으십시오
Thomas Kejser

답변:


11

글쎄, 나는 사용자 정의 postgres C 확장을 작성하는 데 시간을 보냈고 BK 트리 구조를 메모리에 유지하는 Cython 데이터베이스 래퍼를 작성하는 것을 마무리했다.

기본적으로 데이터베이스에서 파시 값의 메모리 내 사본을 유지 관리하며 데이터베이스에 대한 모든 업데이트는 BK 트리로 재생됩니다.

여기 모두 github에 있습니다 . 또한 많은 단위 테스트가 있습니다.

거리가 4 인 항목에 대해 천만개의 해시 값 데이터 세트를 쿼리하면 트리 값의 ~ 0.25 % -0.5 %를 건드리고 ~ 100ms가 걸립니다.


메모리에 1600 만 개의 행이있는 메모리의 BK-Tree? 나는 메모리 크기가 큰 각 이미지에 1000 개의 이미지와 2000 개의 설명자가있는 비슷한 것을보고있었습니다.
스튜어트

@ 스튜어트-이것의 대부분은 해시의 크기에 달려 있습니다. 필자의 경우 해시 값 출력은 int64로 저장하는 단일 64 비트 비트 필드입니다. 훨씬 더 큰 파시 데이터 형식을 가진 것 같습니다. 또한 다른 데이터 유형에서 검색이 어떻게 작동하는지 잘 모르겠습니다. 그들은 여전히 ​​미터법 공간입니까? 거리는 어떻게 계산합니까?
가짜 이름

opencv와 함께 제공된 FLANN marcher와 함께 32 비트 설명자를 사용하고 있습니다. 거리를 계산하기 위해 Lowe의 비율에 따라 임계 값으로 해밍을 사용합니다. 이 시점에서 KD 트리 구조를 제공하거나 사용자와 더 유사한 솔루션으로 전환하는 메모리 FLANN을 사용하는 것이 가장 좋은지 잘 모르겠습니다. 왜 자신을 굴려서 libflann과 같은 것을 가지지 않았습니까?
스튜어트

@ 스튜어트-나는 내 자신을 굴리지 않았다. 슈퍼 보링 DFT 기반 해싱을 사용하고 있습니다.
가짜 이름

7

무어 대답!

좋아, 마침내 사용자 정의 PostgreSQL 인덱싱 확장을 작성하는 데 시간이 걸렸습니다. 내가 사용 SP-GIST 인터페이스를 .

이것은 대부분 Posgres가 크기 때문에 상당히 어려웠습니다 .

어쨌든 평소와 같이 github 여기 있습니다 .

성능 측면에서,이 질문에 대한 다른 대답에서 현재 메모리 내 구현보다 ~ 2 ~ 3 배 느리지 만 사용하는 것이 훨씬 편리합니다. 성능 히트를 행복하게 먹을 것입니다 (실제로 ~ 50입니다) ms / query-150ms / query, 여전히 작습니다).


당신은 굉장합니다! 설치 방법에 대한 README를 추가 할 수 있습니까? Postgres : P
HypeWolf

1
@HypeWolf-저장소의 루트 에는 README가 있습니다. 그것은 당신이 원하는 것을 다루지 않습니까?
가짜 이름

내 실수, 나는 그것을 보지 못했다, 내가 어디에서 찾고 있는지 모르겠다 : /
HypeWolf

README도 찾고있었습니다. 루트 폴더에 있습니다. 링크가 일부 하위 폴더로 연결됩니다. 혼란 스러웠습니다.
luckydonald
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.