Разборка одного случая, когда запрос под Администратором выполнялся значительно быстрее чем под обычным пользователем, показала, что вина лежит на дополнительном условии с вызовом функции G_SEC_TEST.
Появление UDF функции в секции WHERE запроса часто сводит с ума оптимизатор и приводит к ужасным планам. Если проверку на права доступа перенести на уровень клиента, внутрь датасета, сразу после считывания записи с сервера и перед копированием ее во внутренний буфер, то получим выигрыш в тех случаях, когда у пользователя есть права на большинство записей в результате выборки. В противном случае — перенос проверки на клиента породит избыточный трафик по сети.
Слаще ли хрен редьки выяснить можно только экспериментальным путем.
Вот, если бы заранее знать долю записей на которые у текущего пользователя есть/отсутствуют права...
13 комментариев:
А G_SEC_TEST не заменяется стандартными BIN_AND и BIN_OR ?
Можно заменить:
G_SEC_TEST(z.aview, ingroup) <> 0
эквивалентно
BIN_AND(BIN_OR(z.aview, 1), ingroup) <> 0
но, у нас для группы Администраторы условия
вообще не подставляются в запрос, так что
можно оставить:
BIN_AND(z.aview, ingroup) <> 0
Однако, проблемы с искажением плана это не решит.
А можно пример как из-за этого меняется план?
Это к Ал-ре в понедельник.
Александра говорит, что план не менялся, а просто тормозило с G_SEC_TEST. Тогда я думаю нужно заменить ф-цию из UDF на встроенную. Плюс можно попробовать так ((BIN_AND(BIN_OR(z.aview, 1), ingroup) + 0 <> 0), тогда точно план не изменится
Не будем спорить по пустому. Менялся именно план. В одном случае из таблицы gd_document шло несколько сотен чтений, в другом -- 800 тыс. Такая элементарная функция, как G_SEC_TEST не может ничего замедлить. Ее выполнение -- это доли процента от общих затрат на вычисление нужной страницы, чтение страницы с диска, извлечение записи из страницы, анализ полей по условиям запроса, пересылку результата по сети.
Тогда это баг FB в данном случае. Почему в данном случае должен меняться план, это например если бы использовали какой-нить coalesce и с ним менялся бы план выполнения...
При замене на BIN_AND-BIN_OR план остался таким же, как и при использовании G_SEC_TEST.
Естественно. Еще не хватало, чтобы оптимизатор вчитывался в имена функций.
вроде нет бага
просто при выполнении запроса делается не fetchall и под Админом вытягивается не все записи
а под пользователем, т.к. есть ограничение, то в буфер который отправляется клиенту не хватает записей из тех которые отправлялись Админу, и сервер сканирует выдачу дальше и дальше, вот и набирается 800000 записей из gd_document
как-то так
Точнее не так, вы попробуйте выполнить два этих запроса в IBE где стоит параметр fetch all и разницы не будет. А то что выбиралось 800тыс записей без фильтра на клиент, так это наши проблемы.
Там не на клиента. Там в статистике запроса показывалось 800 т. чтений в одном случае.
Сделайте fetch all, будет 800тыс. в обоих вариантах.
Отправить комментарий