Добро пожаловать в мой блог! Изначально он не задумывался как блог CRM разработчика, но жизнь сама внесла нужные коррективы. Тут я публикою все свои наблюдения относительно обозначенных в заголовке систем. Если Вы найдете в нем что-то интересное для Вас, как для заказчика, то буду рад сотрудничать с Вами! В моей компетенции 100% задач по MS CRM 3.0/4.0/2011:
MVP 2010, 2011
- Консалтинг
- Проектирование
- Разработка
- Обучение
MVP 2010, 2011
Парметр TotalRecordCount и проблемы производительности. Как отключить подсчет количества записей в представлении
Запись от Артем Enot Грунин размещена 13.06.2012 в 21:38
Обновил(-а) Артем Enot Грунин 14.06.2012 в 00:41
Обновил(-а) Артем Enot Грунин 14.06.2012 в 00:41
Как вы, наверно, знаете CRM 2011 внесла инновацию, которую просили многие пользователи: системный счетчик записей в представлении:
Инновация работает и с SDK методами. При построении Fetch и QueryExpression запросов мы можем указать в параметрах PagingInfo, что мы хотим получить не только страницу записей и ключ MoreRecords, но и полное количество записей. Для QueryExpression код может выглядеть так:
Аналогичный параметр можно использовать и в Fetch запросе, что по умолчанию и делают все системные представления.
Существует так же глобальная настройка развертывания CRM доступная через параметры ConfigDB в Deployment Service: AggregateQueryRecordLimit. По умолчанию она равна 5000 записей. Столько записей по умолчанию разрешено для использования в агрегирующих запросах, в том числе COUNT. В нашем примере, если в таблице больше 5000 записей, система не покажет полное количество, а
покажет "5000+".
Почему вводится это ограничение? Дело в том что цена использования ReturnTotalRecordCount (равно как и любой другой агрегации) может быть достаточно высока: подсчет количества записей осуществляется с учетом прав доступа! Иными словами, для того чтобы отобразить в списке 50 записей, система проверяет доступ к 5000 записей, если они есть в базе! В случае со сложной моделью безопасности, при использовании Групп (Team) и предоставления доступа (Share) подобные визуальные излишества могут завалить SQL сервер любой мощности. Что и случилось на моем проекте.
К счастью, CRM 2011 Update Rollup 6 вносит дополнения функционала, которые могут спасти ситуацию. В загадочную таблицу OrgDBOrgSettings добавлен параметр SkipGettingRecordCountForPaging который позволяет отключить вызов инструкии
при каждом обновлении представления.
Для его изменения, вероятно, можно использовать DeploymentService, однако я не смог найти нужную настройку в SDK. Статья базы знаний по Update Rollup 6 советует использовать утилиту OrgDBOrgSettings Tool, которая теперь поставляется вместе с пакетами обновлений. На текущий момент, утилита доступна только для английского языка, так что если вы качаете обновления только для русской версии CRM, вы легко могли упустить факт ее появления в английском пакете обновления.
Утилита представлена консольным приложением с двумя единственными командами: чтение настроек организации и изменение конкретного параметра. Корректно настроив конфиг программы (не так и просто - читайте мануал!) и выполнив команду
Мы отключим выполнение счетчика записей:
Производительности вашей системы больше не угрожает ничего, кроме кривого кода. Удачи!
p.s. Совсем забыл один важный момент. При включении параметра SkipGettingRecordCountForPaging, система будет игнорировать параметр ReturnTotalRecordCount не только при обновлении представлений, но, в том числе, и в запросах из вашего кода! Если вам все же нужно знать количество записей, которые удовлетворяют условиям выборки прежде чем приступить к ней - используйте агрегацию Fetch: Use FetchXML Aggregation.
Инновация работает и с SDK методами. При построении Fetch и QueryExpression запросов мы можем указать в параметрах PagingInfo, что мы хотим получить не только страницу записей и ключ MoreRecords, но и полное количество записей. Для QueryExpression код может выглядеть так:
X++:
PagingInfo p = new PagingInfo(); p.ReturnTotalRecordCount = true; QueryExpression q = new QueryExpression(); q.PageInfo = p;
Существует так же глобальная настройка развертывания CRM доступная через параметры ConfigDB в Deployment Service: AggregateQueryRecordLimit. По умолчанию она равна 5000 записей. Столько записей по умолчанию разрешено для использования в агрегирующих запросах, в том числе COUNT. В нашем примере, если в таблице больше 5000 записей, система не покажет полное количество, а
покажет "5000+".
Почему вводится это ограничение? Дело в том что цена использования ReturnTotalRecordCount (равно как и любой другой агрегации) может быть достаточно высока: подсчет количества записей осуществляется с учетом прав доступа! Иными словами, для того чтобы отобразить в списке 50 записей, система проверяет доступ к 5000 записей, если они есть в базе! В случае со сложной моделью безопасности, при использовании Групп (Team) и предоставления доступа (Share) подобные визуальные излишества могут завалить SQL сервер любой мощности. Что и случилось на моем проекте.
К счастью, CRM 2011 Update Rollup 6 вносит дополнения функционала, которые могут спасти ситуацию. В загадочную таблицу OrgDBOrgSettings добавлен параметр SkipGettingRecordCountForPaging который позволяет отключить вызов инструкии
Код:
select COUNT(*) as [#TotalRecordCount]
Для его изменения, вероятно, можно использовать DeploymentService, однако я не смог найти нужную настройку в SDK. Статья базы знаний по Update Rollup 6 советует использовать утилиту OrgDBOrgSettings Tool, которая теперь поставляется вместе с пакетами обновлений. На текущий момент, утилита доступна только для английского языка, так что если вы качаете обновления только для русской версии CRM, вы легко могли упустить факт ее появления в английском пакете обновления.
Утилита представлена консольным приложением с двумя единственными командами: чтение настроек организации и изменение конкретного параметра. Корректно настроив конфиг программы (не так и просто - читайте мануал!) и выполнив команду
X++:
OrgDBOrgSettingsTool.exe Update /u < > SkipGettingRecordCountForPaging True
Производительности вашей системы больше не угрожает ничего, кроме кривого кода. Удачи!
p.s. Совсем забыл один важный момент. При включении параметра SkipGettingRecordCountForPaging, система будет игнорировать параметр ReturnTotalRecordCount не только при обновлении представлений, но, в том числе, и в запросах из вашего кода! Если вам все же нужно знать количество записей, которые удовлетворяют условиям выборки прежде чем приступить к ней - используйте агрегацию Fetch: Use FetchXML Aggregation.
Всего комментариев 0