LINUX.ORG.RU

Индекс для UUID

 , ,


0

1

Использую Postresql.

Есть таблица Documents с полями:

Account тип bigint Document тип bigint

User тип UUID

Есть 2 индекса

CREATE INDEX "AccountDocument" ON "Documents" USING btree ("Account" NULLS LAST, "Document" NULLS LAST)
WHERE ("Account" IS NOT NULL OR "Document" IS NOT NULL);
CREATE INDEX "AccountUserDocument" ON "Documents"  USING btree ("Account", "User", "Document")

Для простого запроса хочу, чтобы использовался индекс AccountUserDocument

SELECT *
FROM "Documents"
WHERE "Account" = 1
AND "USER" = 'dd758b54-55b3-442a-804b-8a3d311432ba'::UUID 
AND "Document" = 2
но используется индекс AccountDocument
"Index Scan using "AccountDocument" on "Documents"  (cost=0.29..8.31 rows=1 width=73) (actual time=0.016..0.016 rows=0 loops=1)"
"  Index Cond: ("Document" = 2)"
"  Filter: (("Account" = 1) AND ("USER" = 'dd758b54-55b3-442a-804b-8a3d311432ba'::uuid))"
"  Buffers: shared hit=2"
"Planning time: 1.026 ms"
"Execution time: 0.039 ms"
только есть указать у индекса AccountUserDocument тип индекса gist, то он используется
"Index Scan using "AccoutUserDocument" on "Documents"  (cost=0.28..8.30 rows=1 width=73) (actual time=3.626..3.626 rows=0 loops=1)"
"  Index Cond: (("User" = 'dd758b54-55b3-442a-804b-8a3d311432ba'::uuid) AND ("Document" = 2))"
"  Filter: ("Account" = 1)"
"  Buffers: shared hit=73"
"Planning time: 0.946 ms"
"Execution time: 3.652 ms"
Почитал инфу про тип gist он обычно используется для полнотекстового поиска.

Вопрос почему индекс не используется с типом btree, только из-за того, что в индексе есть поле UUID?

Возможно PostgreSQL решил что селективность и так хорошая и нет смысла использовать более крупный индекс. Попробуй данных побольше залить.

maxcom ★★★★★ ()

На сколько я знаю, postgres сам выбирает какой индекс использовать. Можешь дропнуть второй индекс, если он не сильно нужен на самом деле

Вопрос почему индекс не используется с типом btree, только из-за того, что в индексе есть поле UUID?

В каком смысле «не используется»? У тебя там Index Scan, индекс используется, прост postgres решил, что этот индекс лучше.

Aswed ★★★★★ ()
Ответ на: комментарий от no-such-file

Ок, возьмите 2 64-битных. Нафиг вам черточки в записи? Что от чего вы ими разделяете и зачем?

Не рандомное - ну возьмите нормальный генератор + хеш от счетчика циклов проца.

kilokolyan ()
Последнее исправление: kilokolyan (всего исправлений: 1)
Ответ на: комментарий от kilokolyan

Нафиг вам черточки в записи

Какие чёрточки, ты больной? Uuid храниться в бинарном виде, просто как 16 байт.

ну возьмите нормальный генератор + хеш от счетчика циклов проца

Проблема совсем не в этом, а в том, чтобы оно было рандомное И уникальное в кластере. Для этого там чёрточки в представлении, они разделяют id машины, время генерации, номер внутри секунды и версию. Прочитай уже мануал, балбес.

no-such-file ★★★★★ ()
Последнее исправление: no-such-file (всего исправлений: 2)
Ответ на: комментарий от kilokolyan

Int64 мало. По парадоксу дней рожденья нужно 2^32 записей чтобы иметь шанс поймать дубликат. 128 битов уже хватает. А чёрточки это просто формат. Хранить в виде текста необязательно.

Legioner ★★★★★ ()
Ответ на: комментарий от kilokolyan

В студию их.

Гугли спецификации. Или статью на википедии открой, там и описание, и примеры софта, и расчет вероятности коллизий. Вкратце, там в определенных типах uuid’ов используется инфа типа даты-времени и MAC-адреса. Есть и полностью рандомные.

Думаешь, ты один умный со своим интом?

anonymous ()
Ответ на: комментарий от anonymous

Я думаю что обьективно невозможно ничего уникальнее равномерно распределённого генератора рандома 128-битного. Зависеть от маков - странно, учитывая их лёгкий клон или проставление в 112233445566 на всяких эмуляторах.

kilokolyan ()