Швидкі запити на відстань у постгресі


15

У мене є велика база даних (16М рядків), що містить перцептивні хеші зображень.

Я хотів би мати можливість шукати рядки, забиваючи відстань у розумні часові рамки.

Наразі, наскільки я правильно розумію проблему, я вважаю, що найкращим варіантом тут була б спеціальна реалізація SP-GiST, яка реалізує BK-дерево , але це, здається, багато роботи, і я все ще нечіткий на практичному подробиці правильної реалізації спеціального індексу. Розрахунок відстані Хеммінга є слухняною досить, і я зробити знаю , C, хоча.

В основному, що тут є відповідним підходом? Мені потрібно мати можливість запитувати відповідність на певній відстані редагування хеша. Як я розумію, відстань Левенштейна з рядками однакової довжини є функціонально перешкодою, тому існує хоча б якась підтримка того, чого я хочу, хоча чіткого способу створити з нього індекс немає (пам’ятайте, значення, за яким я запитую Я не можу попередньо обчислити відстань від фіксованого значення, оскільки це було б корисно лише для цього одного значення).

Зараз хеші зберігаються як 64-знакова рядок, що містить двійкове ASCII-кодування хеша (наприклад, "10010101 ..."), але я можу їх легко перетворити в int64. Справжнє питання полягає в тому, що мені потрібно мати можливість запитувати порівняно швидко.

Здається, що можна досягти чогось із того, що я хочу з pg_trgm, але мені трохи не зрозуміло, як працює механізм відповідності триграму (зокрема, що насправді представляє показник подібності, який він повертає ?) на кшталт редагування-відстань).

Ефективність вставки не є критичною (обчислити хеші для кожного ряду дуже дорого), тому я в першу чергу дбаю про пошук.


У розширенні smlar може бути те, що вам потрібно: pgcon.org/2012/schedule/attachments/252_smlar-2012.pdf або pg_s подобниity: pgcon.org/2009/schedule/attachments/108_pg_s подобниity.pdf
Ніл

@NeilMcGuigan - Цікаво! Перша презентація насправді від людей, які підтримують системи SP-GiST та GIST у постгресах.
Підроблене ім’я

Перше посилання є для чогось принципово іншого. вони шукають встановлені перехрестя, тоді як я шукаю дистанцію забивання. Я міг би фінансувати фази в набір, але це було б надзвичайно безладним і вимагало б багато коду підтримки скрізь.
Підроблене ім’я

FWIW, На даний момент я більш-менш зробив висновок, що мені потрібно впровадити власну систему індексації. Я зараз переглядаю спеціальні індекси SP-GiST, але поняття не маю, що я роблю.
Підроблене ім’я

1
@FakeName: Коли ви говорите відстань забивання, я припускаю, що ви маєте на увазі відстань забивання рядків хеш-значень, а не зображення? Іншими словами, ви хочете запитати: Знайдіть усі значення хешу, які є бітовими підстановками від вхідного параметра
Thomas Kejser

Відповіді:


11

Ну, я витратив деякий час на перегляд написання користувальницького розширення Postgres C і завершив написання обгортки бази даних Cython, яка підтримує структуру BK-дерева в пам'яті.

В основному, він зберігає в пам'яті копію фаш-значень з бази даних, і всі оновлення бази даних відтворюються в BK-дерево.

Це все на GitHub тут . Він також має багато одиничних тестів.

Запит через набір даних із 10 мільйонів хеш-значень для елементів, що мають відстань у 4, призводить до торкання ~ 0,25% -0,5% значень дерева та займає ~ 100 мс.


BK-Дерево пам’яті з 16 мільйонами рядків пам’яті? Я дивився на щось подібне, однак з 1000 зображень та 2000 дескрипторів на кожне зображення мій об'єм пам'яті був величезним.
Стюарт

@Stewart - Багато чого залежить від розміру вашого хешу. У моєму випадку вихід хеш-значень - це єдине 64-розрядне бітове поле, яке я зберігаю як int64. Здається, у вас набагато більший тип даних фаша. Я також не впевнений, як би працювали пошуки в іншому подібному вигляді. Вони все ще метричний простір? Як ви обчислюєте відстань?
Підроблена назва

Я використовую 32-бітові дескриптори з маршем FLANN, що постачається з opencv. Для обчислення відстані я використовую ногу з порогом, виходячи з коефіцієнта Лоу. На даний момент я не впевнений, чи найкраще спробувати дотримуватися пам'яті FLANN, яка забезпечує структуру дерева KD, або перейти до рішення, більш схожого на ваше. Чому ти в кінцевому підсумку розгорнув свій власний і не пішов на щось на зразок libflann?
Стюарт

@Stewart - я не скочував свою. Я використовую супер нудне хешування на основі DFT .
Підроблена назва

7

ВІДПОВІДИ МОРУ!

Гаразд, я нарешті знайшов час, щоб написати спеціальне розширення для індексації PostgreSQL. Я використовував інтерфейс SP-GiST .

Це було досить складно, головним чином тому, що Погрес великий .

У будь-якому випадку, як зазвичай, це на GitHub тут .

Виконання продуктивності, в даний час ~ в 2-3 рази повільніше, ніж реалізація чистої пам’яті в моїй іншій відповіді на це запитання, але це набагато зручніше використовувати, я з радістю з'їм цей показник ефективності (реально, це ~ 50 ms / query - 150 мс / запит, що ще досить мало).


Ти надзвичайний! Чи можете ви додати README про те, як встановити? Я ніколи насправді нічого не встановлював у Postgres: P
HypeWolf

1
@HypeWolf - Корінь репо має README . Це не покриває те, що ви хочете?
Підроблена назва

Моя помилка, я її не бачив, я не впевнений, куди дивився: /
HypeWolf

Шукав також README. Це в кореневій папці. Посилання переходить до деякої підпапки. Це було заплутано.
luckydonald
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.