rum. Использование RUM индексов#
В исходном дистрибутиве установлено по умолчанию: нет.
Связанные компоненты: отсутствуют.
Схема размещения:
ext.
Индексный метод доступа RUM является одним из инструментов оптимизации доступа к данным. RUM основан на GIN-подобном индексном методе и включает дополнительную методику оценки релевантности результата поиска («дистанцией»).
Функциональность поставляется в качестве расширения в составе продукта, не требует специальных шагов по настройке со стороны сотрудников сопровождения. Активация расширения не требует изменения параметров конфигурации БД.
RUM имеет качественное преимущество в возможности ранжирования результатов поиска по «дистанции»/«схожести». При этом «дистанция»/«схожесть» имеют другой алгоритм обработки, чем существующие функции ts_rank, ts_rank_cd.
Для незначительного уменьшения размера индекса можно использовать классы операторов hash, если не предполагается префиксного поиска.
RUM имеет количественное преимущество перед существующими индексными методами только при соблюдении следующих условий:
Запрос SQL должен иметь условие поиска по дистанции. В случае FTS -
tsqueryдолжен использовать оператор дистанции«<=>»,«<2>»,«<3>»и тому подобные.Запрос SQL, содержащий условие поиска по дистанции, должен оперировать термами низкой или средней селективности (при возможности их оценки).
В иных случаях предпочтительнее использовать другие индексы.
Расширение предоставляет индексный метод RUM, реализующий следующие классы операторов:
Класс операторов |
Оператор |
Тип операнда 1 |
Тип операнда 2 |
Комментарий |
|---|---|---|---|---|
Операторы вне классов операторов |
|
|
|
Дистанция между операндами |
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
|
Дистанция только для операнда 2 |
|
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
|
Дистанция только для операнда 1 |
|
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
- |
||
|
|
|
Сходство массивов. Под сходством определяется: |
|
|
|
|
|
Пересечение операндов |
|
|
|
|
Пересечение операндов |
|
Дистанция между операндарми |
|||
|
|
|
|
Пересечение операндов. |
|
Дистанция между операндами |
|||
|
|
|
|
Пересечение операндов |
|
|
|
|
Пересечение операндов. |
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
Дистанция между операндами |
|||
|
Дистанция только для операнда 2 |
|||
|
Дистанция только для операнда 1 |
|||
|
|
|
- |
|
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
Дистанция между операндами |
|||
|
Дистанция только для операнда 2 |
|||
|
Дистанция только для операнда 1 |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
Дистанция между операндами |
|||
|
Дистанция только для операнда 2 |
|||
|
Дистанция только для операнда 1 |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
Дистанция между операндами |
|||
|
Дистанция только для операнда 2 |
|||
|
Дистанция только для операнда 1 |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
Дистанция между операндами |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
Дистанция между операндами |
|||
|
Дистанция только для операнда 2 |
|||
|
Дистанция только для операнда 1 |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
Дистанция между операндами |
|||
|
Дистанция только для операнда 2 |
|||
|
Дистанция только для операнда 1 |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
Дистанция между операндами |
|||
|
Дистанция только для операнда 2 |
|||
|
Дистанция только для операнда 1 |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
Дистанция между операндами |
|||
|
Дистанция только для операнда 2 |
|||
|
Дистанция только для операнда 1 |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
- |
|
- |
|||
|
- |
|||
|
- |
|||
|
- |
|||
|
Дистанция между операндами |
|||
|
|
|
|
Класс операторов не поддерживает определение сходства и дистанции |
|
- |
|||
|
- |
|||
|
- |
|||
|
|
|
|
Класс операторов предназначен для раздельного хранения |
|
|
|
|
Класс операторов предназначен для раздельного хранения |
|
|
|
|
Класс операторов предназначен для раздельного хранения |
|
|
|
|
Класс операторов предназначен для раздельного хранения |
Примечание:
В столбце Класс операторов класс по умолчанию для сочетания операндов.
Операторы
@@,<=>,&&,<,<=,=>,>,<являются коммутативными.
Функции#
Расширение добавляет следующие публичные функции (за исключением функций, обеспечивающих работу операторов или классов операторов):
Функция |
Описание |
|---|---|
|
Расчет дистанции между |
|
Расчет рейтинга между |
Метод подсчета – битовая маска, учитывающая нормализацию распределения веса к объему документа и соответствующая таковой в функции ts_rank_cd индекса GIN.
Метод подсчета |
Значение маски |
Описание |
|---|---|---|
|
0x00 |
Длина документа не учитывается |
|
0x01 |
Ранг документа делится на сумму единицы и логарифма длины документа |
|
0x02 |
Ранг документа делится на его длину |
|
0x04 |
Ранг документа делится на среднее гармоническое расстояние между блоками |
|
0x08 |
Ранг документа делится на число уникальных слов в документе |
|
0x10 |
Ранг документа делится на сумму единицы и логарифма числа уникальных слов в документе |
|
0x20 |
Ранг делится на значение, которое на единицу больше самого ранга |
Доработка#
Доработка не проводилась.
Ограничения#
Ограничения отсутствуют.
Установка#
Установка расширения производится в выбранной БД следующим способом:
SET ROLE db_admin;
CREATE EXTENSION IF NOT EXISTS rum WITH SCHEMA ext;
RESET ROLE;
Отключение расширения#
Отключение расширения влечет за собой удаление всех ранее созданных индексов RUM, дальнейшую невозможность использовать классы операторов, операторы и функции, добавленные расширением. Отключение функциональности требует прав db_admin.
Удаление расширения производится следующим способом:
SET ROLE db_admin;
DROP EXTENSION IF EXISTS rum CASCADE;
RESET ROLE;
Настройка#
Настройка не требуется.
Использование модуля#
Подготовительные действия#
Создайте расширение
rum:SET ROLE db_admin; CREATE EXTENSION IF NOT EXISTS rum WITH SCHEMA ext; CREATE SCHEMA IF NOT EXISTS test AUTHORIZATION as_admin; RESET ROLE; SET ROLE as_admin;Создайте конфигурации FTS и словаря:
CREATE TEXT SEARCH DICTIONARY ext.english_hunspell ( TEMPLATE = pg_catalog.ispell, dictfile = 'en', afffile = 'en', stopwords = 'english' ); CREATE TEXT SEARCH CONFIGURATION ext.english_dict (COPY=pg_catalog.english); ALTER TEXT SEARCH CONFIGURATION ext.english_dict ALTER MAPPING FOR asciihword ,asciiword ,hword ,hword_asciipart ,hword_part ,word WITH ext.english_hunspell, english_stem;Скопируйте конфигурации со стеммером:
CREATE TEXT SEARCH CONFIGURATION ext.english (COPY=pg_catalog.english);Создайте таблицу для тестов (вариант RUM):
CREATE TABLE test.tbl_rum (LIKE test.tbl_plain INCLUDING ALL);Создайте FTS индексы:
CREATE INDEX tbl_gin_to_tsvector_idx ON test.tbl_gin USING gin (to_tsvector('ext.english_dict'::regconfig, val)); CREATE INDEX tbl_gin_to_tsvector_idx1 ON test.tbl_gin USING gin (to_tsvector('ext.english'::regconfig, val)); CREATE INDEX tbl_rum_to_tsvector_idx ON test.tbl_rum USING rum (to_tsvector('ext.english_dict'::regconfig, val)); CREATE INDEX tbl_rum_to_tsvector_idx1 ON test.tbl_rum USING rum (to_tsvector('ext.english'::regconfig, val)); RESET ROLE;
Сценарии использования#
Использование индекса в сценарии FTS, использующего операторы дистанции, FTS словарь#
Запустите блок кода (использование FTS без индексов):
EXPLAIN (ANALYZE,BUFFERS) SELECT id ,pattern ,tsv_txt ,tsq ,val FROM (SELECT ts_headline('ext.english_dict',val,tsq,'HighlightAll=true,StartSel=<<*,StopSel=*>>') pattern ,id ,regexp_split_to_array(tsv::text,' ') tsv_txt ,tsv ,tsq ,val FROM (SELECT id ,to_tsquery('ext.english_dict','database <2> server & !sql') tsq ,to_tsvector('ext.english_dict',tp.val) tsv ,val FROM test.tbl_plain tp ) tbl ) raw WHERE tsv @@ tsq ORDER BY ts_rank(tsv,tsq) DESC;Ожидаемый результат — выполнение без ошибок.
Запустите блок кода (использование FTS с индексом GIN):
EXPLAIN (ANALYZE,BUFFERS) SELECT id ,pattern ,tsv_txt ,tsq ,val FROM (SELECT ts_headline('ext.english_dict',val,tsq,'HighlightAll=true,StartSel=<<*,StopSel=*>>') pattern ,id ,regexp_split_to_array(tsv::text,' ') tsv_txt ,tsv ,tsq ,val FROM (SELECT id ,to_tsquery('ext.english_dict','database <2> server & !sql') tsq ,to_tsvector('ext.english_dict',tp.val) tsv ,val FROM test.tbl_gin tp ) tbl ) raw WHERE tsv @@ tsq ORDER BY ts_rank(tsv,tsq) DESC;В плане запроса присутствует шаг
Recheck cond.Запустите блок кода (использование FTS с индексом RUM):
EXPLAIN (ANALYZE,BUFFERS) SELECT id ,pattern ,tsv_txt ,tsq ,val FROM (SELECT ts_headline('ext.english_dict',val,tsq,'HighlightAll=true,StartSel=<<*,StopSel=*>>') pattern ,id ,regexp_split_to_array(tsv::text,' ') tsv_txt ,tsv ,tsq ,val FROM (SELECT id ,to_tsquery('ext.english_dict','database <2> server & !sql') tsq ,to_tsvector('ext.english_dict',tp.val) tsv ,val FROM test.tbl_rum tp ) tbl ) raw WHERE tsv @@ tsq ORDER BY ts_rank(tsv,tsq) DESC;В плане запроса отсутствует шаг
Recheck cond. Стоимость запроса в шаге 3 меньше или равна стоимости запроса в шаге 2.
Влияние на производительность. Оценка стоимости дискового хранения#
Для таблицы
tbl_rumдобавьте индексы, использующие класс операторовrum_tsvector_hash_ops. Реиндексируйте таблицы:CREATE INDEX IF NOT EXISTS tbl_rum_to_tsvector_idx2 ON test.tbl_rum USING rum(to_tsvector('ext.english_dict'::regconfig, val) rum_tsvector_hash_ops); CREATE INDEX IF NOT EXISTS tbl_rum_to_tsvector_idx3 ON test.tbl_rum USING rum(to_tsvector('ext.english'::regconfig, val) rum_tsvector_hash_ops); REINDEX TABLE test.tbl_plain; REINDEX TABLE test.tbl_rum; REINDEX TABLE test.tbl_gin;Ожидаемый результат — выполнение без ошибок.
Сравните размеры индексов для всех таблиц:
SELECT c.oid::regclass::text ,c.relkind,pg_get_indexdef(c.oid) ,pg_relation_size(c.oid) FROM pg_class c JOIN pg_namespace ns ON c.relnamespace=ns.oid WHERE ns.nspname='test' ORDER BY 1,2;Размеры индексов ранжируются в порядке (от меньшего к большему):
GIN;
RUM (
rum_tsvector_hash_ops);RUM (превышает размер индекса GIN примерно в 2 раза. Превышает размер таблицы).
Ссылки на документацию разработчика#
Дополнительно поставляемый модуль rum: https://github.com/postgrespro/rum.