Мы меняем структуру БД (PostgreSQL 10.11) для одного из наших проектов. И одно из изменений - это перемещение поля типа uuid [] (называемого «areaoflawid») в поле jsonb (называемое «data»).
Итак, у нас есть таблица, которая выглядит следующим образом:
CREATE TABLE public.documents
(
id serial,
areasoflawid uuid[], --the field to be moved into the ‘data’
data jsonb,
….
)
Мы не меняем значения массива или его структуры. т.е. Documents.data -> 'metadata' -> 'areaoflawids' содержит те же элементы, что и documents.areasoflawid) После переноса данных JSON, хранящиеся в поле «data», имеют следующую структуру:
{
...
"metadata": {
...
"areaoflawids": [
"e34e0ee5-78e0-4d92-9186-ac69c109408b",
"b3af9163-d910-4d19-8f40-0602b75c25b0",
"50dc7fd8-ebdf-4cd2-bcab-b8d755fe96e8",
"8955c062-363f-4a1a-ac3c-d1c2ffe96c9b",
"bdb79f9f-4539-45f5-ac82-92baaf915f6c"
],
....
},
...
}
Итак, после переноса данных мы начали сопоставлять запросы, связанные с полями jsonb, и выяснили, что поиск по полю массива documents.data -> 'metadata' -> 'areaoflawids' НАМНОГО дольше, чем поиск по полю uuid [] documents.areasoflawid. 1009 *
Вот запросы:
--search over jsonb array field, takes 6.2 sec, returns 13615 rows
SELECT id FROM documents WHERE data->'metadata'->'areaoflawids' @> '"e34e0ee5-78e0-4d92-9186-ac69c109408b"'
--search over uuid[] field, takes 600ms, returns 13615 rows
SELECT id FROM documents WHERE areasoflawid @> ARRAY['e34e0ee5-78e0-4d92-9186-ac69c109408b']::uuid[]
Вот поле индекса над jsonb:
CREATE INDEX test_documents_aols_gin_idx
ON public.documents
USING gin
(((data -> 'metadata'::text) -> 'areaoflawids'::text) jsonb_path_ops);
А вот и план выполнения:
EXPLAIN ANALYZE SELECT id FROM documents WHERE data->'metadata'->'areaoflawids' @> '"e34e0ee5-78e0-4d92-9186-ac69c109408b"'
"Bitmap Heap Scan on documents (cost=6.31..390.78 rows=201 width=4) (actual time=2.297..5859.886 rows=13614 loops=1)"
" Recheck Cond: (((data -> 'metadata'::text) -> 'areaoflawids'::text) @> '"e34e0ee5-78e0-4d92-9186-ac69c109408b"'::jsonb)"
" Heap Blocks: exact=4859"
" -> Bitmap Index Scan on test_documents_aols_gin_idx (cost=0.00..6.30 rows=201 width=0) (actual time=1.608..1.608 rows=13614 loops=1)"
" Index Cond: (((data -> 'metadata'::text) -> 'areaoflawids'::text) @> '"e34e0ee5-78e0-4d92-9186-ac69c109408b"'::jsonb)"
"Planning time: 0.133 ms"
"Execution time: 5862.807 ms"
Другие запросы к полю jsonb работают с приемлемой скоростью, но этот конкретный поиск примерно в 10 раз медленнее, чем поиск по разделенному полю. Мы ожидали, что это будет немного медленнее, но не так уж плохо. Мы рассматриваем возможность оставить это поле «Площадь незаконного» как отдельное поле, но мы определенно предпочли бы переместить его в json. Я играл с разными индексами и операциями (также использовал? И? |), Но поиск все еще медленный. Любая помощь приветствуется!