Обсуждение: RE: [pgsql-ru-general] Зацените типчик

Поиск
Список
Период
Сортировка

RE: [pgsql-ru-general] Зацените типчик

От
"Ilia Kantor"
Дата:

> -----Original Message-----
> From: Andrey N. Oktyabrski [mailto:ano@antora.ru]
> Sent: Friday, July 07, 2006 4:53 PM
> To: Ilia Kantor
> Subject: Re: [pgsql-ru-general] Зацените типчик
> 
> Ilia Kantor wrote:
> > Когда-то я делал похожую вещь.
> > А именно - поле (или поля) проверки доступа.
> >
> > Поле состояло из массива int[], содержащего ID нужных групп доступа.
> Это довольно громоздко - массивы. Я именно хотел сделать так, чтобы
> девелОперы пользовались - читай чтоб выглядело более-менее привычно, и
> чтобы оверхед поменьше был.
Много групп - несколько прав, вложенные группы. 
Как у тебя такое сделать?

> 
> > Проверка на доступ осуществлялась операцией @.
> > Брались все группы юзера и проверялось, пересекаются ли они с полем.
> >
> > Если да, то право имеет. Сам оператор пересечения @ работал через
> > GIST-индекс.
> > Все пахало достаточно быстро и красиво, благо групп не так много разных.
> >
> > Для того, чтобы оптимизер мог сделать правильный план, пришлось писать
> > собственную статистику по таким полям (т.е по int[]).
> У меня вроде оптимизёр пользуется индексом, проверял. Кстати, забыл там
> в README пример создания индекса показать:
> CREATE INDEX obj_acl_idx ON obj USING gist (acl gist_row_acl_ops);
Да, но тут небольшая проблема. Когда ты делаешь сложный SQL-запрос, то
оптимизатор должен подсчитать предполагаемое количество результатов каждого
джойна и каждой выборки (селективность).

ГИСТ-индексы в простейшем случае создаются без функции, которая подсчитывает
селективность, с заглушкой - типа всегда 1% от таблицы.

Если ты делаешь сложный запрос, а результатов на самом деле 90%, то
оптимизатор в отсутствии правильной функции и статистики, составит неверный
план.

Хуже всего, когда (в моем случае) есть ряд групп, которые почти всевластны
(95% рядов удовлетворяют запросу) и ряд групп, которые обладают правом на
некоторые объекты (1% рядов или меньше).

Скорее всего, и у тебя возможна такая ситуация, она довольно типична для
прав.

Тогда оптимизатор создает неверный план для всевластных групп (думает что
1%, а там все 99%) и, например, использует Nested Loop в неправильную
сторону (думает что 20 рядов, а там 20000). Результат плачевный, запросы
просто писать нельзя.



> 
> > Однако, как внедрить ее в VACUUM/ANALYZE - неясно, а разработчикам на
> сие
> > накакать, видимо (никто не помог).
> >
> > Так и перешел на Оракл ;)
> Грустная история ;-)
Да, обидно. Ну да постгрес не забываю ;)

> 
> P.S. Ответ был преднамеренно не в рассылку, или туда предназначался? В
> рассылку дублировать это письмо?
Дублируй плиз свое письмо. Мое я продублировал только что.

Re: Зацените т

От
"Andrey N. Oktyabrski"
Дата:
Ilia Kantor wrote:
>>> Когда-то я делал похожую вещь.
>>> А именно - поле (или поля) проверки доступа.
>>>
>>> Поле состояло из массива int[], содержащего ID нужных групп доступа.
>> Это довольно громоздко - массивы. Я именно хотел сделать так, чтобы
>> девелОперы пользовались - читай чтоб выглядело более-менее привычно, и
>> чтобы оверхед поменьше был.
> Много групп - несколько прав, вложенные группы.
> Как у тебя такое сделать?
Я когда планировал, осознавал что ограничения есть и представлял себе
как они выглядят :-) Простой пример: в freebsd есть UFS ACLs. Как часто
этим пользуются? В подавляющем большинстве случаев достаточно
традиционной системы разграничения доступа. Так и здесь. То, что не
лезет в эту модель, будет просто реализовано другими средствами.

Однако, не так уж и много ограничений. Несколько прав есть, вложенные
группы есть. Нет только "много групп" - вместо них три (юзер, группа и
все остальные). Причём, заменить в случае необходимости одного юзера на
список юзеров и один row_acl на массив из них не так уж сложно.

>>> Для того, чтобы оптимизер мог сделать правильный план, пришлось писать
>>> собственную статистику по таким полям (т.е по int[]).
>> У меня вроде оптимизёр пользуется индексом, проверял. Кстати, забыл там
>> в README пример создания индекса показать:
>> CREATE INDEX obj_acl_idx ON obj USING gist (acl gist_row_acl_ops);
> Да, но тут небольшая проблема. Когда ты делаешь сложный SQL-запрос, то
> оптимизатор должен подсчитать предполагаемое количество результатов каждого
> джойна и каждой выборки (селективность).
>
> ГИСТ-индексы в простейшем случае создаются без функции, которая подсчитывает
> селективность, с заглушкой - типа всегда 1% от таблицы.
Что это за функция? Где можно взять пример? Как её подключить - есть
штатные средства, или постгрес хачить? Если второе, скорее всего не
возьмусь, ибо дело неблагодарное.

> Если ты делаешь сложный запрос, а результатов на самом деле 90%, то
> оптимизатор в отсутствии правильной функции и статистики, составит неверный
> план.
>
> Хуже всего, когда (в моем случае) есть ряд групп, которые почти всевластны
> (95% рядов удовлетворяют запросу) и ряд групп, которые обладают правом на
> некоторые объекты (1% рядов или меньше).
>
> Скорее всего, и у тебя возможна такая ситуация, она довольно типична для
> прав.
Надо думать и пробовать моделировать. Если в это упрусь, думать ещё -
как обойти техническую проблему административными средствами.

> Тогда оптимизатор создает неверный план для всевластных групп (думает что
> 1%, а там все 99%) и, например, использует Nested Loop в неправильную
> сторону (думает что 20 рядов, а там 20000). Результат плачевный, запросы
> просто писать нельзя.
Да, звучит логично и печально :-( Но построчное разделение прав всё-таки
нужно, а в обозримом будущем обещают только постолбцовое (которое,
кстати, и мне сильно поможет запретить чтение чего не положено из
таблицы). Так что деваться некуда - либо что-то придумывать, либо менять
инструменты. Перед тем как сделать второе, надо доказать что первое
невозможно :-)

>>> Однако, как внедрить ее в VACUUM/ANALYZE - неясно, а разработчикам на
>>> сие накакать, видимо (никто не помог).
Может, просто не было предусмотрено такое в постгресе?