Повышаем масштабируемость с DIRECTUM 5.4

15 9

С новой версией системы DIRECTUM администраторы могут включить принудительную параметризацию и фильтрованные индексы в SQL Server. Зачем использовать эти возможности SQL? Почему администратору не обойтись без мнения разработчика? Обо всем по порядку в статье.

Принудительная параметризация и фильтрованные индексы

На обработку параметризованных запросов SQL Server тратит меньше времени и ресурсов, чем на непараметризованные. Это достигается за счет использования кэшированного плана запроса. Включение принудительной параметризации позволяет SQL Server все непараметризованные запросы разом «превратить» в параметризованные.

Фильтрованный индекс – индекс, который содержит не все записи таблицы, а только те, которые соответствуют указанным в WHERE критериям. В результате индекс:

  • занимает меньше места,
  • уменьшает затраты на свое обслуживание,
  • повышает производительность запроса и качество плана выполнения,
  • содержит отфильтрованную статистику.

Очевидным местом применения фильтрованных индексов в DIRECTUM являются таблицы, хранящие разнородные данные: справочники и типы карточек документов. Можно установить фильтр по типу справочника или карточки.

Параметры соединения

Использование перечисленных возможностей SQL Server в DIRECTUM стало возможным благодаря изменению значений параметров соединения с SQL:

Все 3 параметра необходимы для фильтрованных индексов, ANSI_NULLS ON – для принудительной параметризации.

В будущих версиях SQL Server компания Microsoft откажется от значения OFF для ANSI_NULLS и CONCAT_NULL_YIELDS_NULL. Использование OFF в будущем будет приводить к ошибкам.

Modern-конфигурация

В версии 5.4 системы DIRECTUM разработана Modern-конфигурация серверной части. В отличие от классической серверной части в Modern параметры соединения с SQL-сервером имеют рекомендуемые Microsoft значения ON.

Применение этой конфигурации позволит вам полностью использовать возможности для уменьшения нагрузки и оптимизации работы системы. Мы предусмотрели средства, которые помогут вам перейти на новую конфигурацию и быть полностью готовым к будущим версиям SQL Server.

Изменение параметров может повлечь несовместимости. Если у вас нет своей разработки, то беспокоиться не о чем. Стандартная поставка DIRECTUM 5.4 полностью соответствует рекомендациям и не содержит несовместимостей. Чтобы выявить несовместимости в вашем прикладном коде, используйте утилиту конвертации ISBL-текстов.

Тестирование системы показало, что принудительная параметризация позволяет добиться снижения нагрузки на процессоры сервера с СУБД на 20%. Эффект зависит от характера нагрузки на СУБД и будет уникален для каждой системы.

При конвертации системы теперь можно выбрать: оставляем классическую серверную часть или переходим на Modern. Чтобы принять решение, воспользуйтесь нашими рекомендациями:

  • если вы серьезно дорабатывали прикладную разработку и использовали много SQL-кода, а фильтрованные индексы и принудительная параметризация вам не нужны, то выбирайте Classic;
  • если в вашей организации используется стандартная поставка DIRECTUM или весь SQL-код разрабатывался с учетом рекомендуемых Microsoft значений параметров соединений, то выбирайте Modern;
  • если же фильтрованные индексы и принудительная параметризация вам нужны, и несовместимости кода есть, то необходимо исправить код и конвертироваться на Modern серверную часть.

При установке системы DIRECTUM 5.4 с нуля по умолчанию используется конфигурация Modern.

 

Конвертируйтесь на новую версию системы и делитесь в комментариях своим опытом оптимизации работы DIRECTUM и SQL Server.

Евгений Куликов

Проводилось ли нагрузочное тестирование? Где-то можно  посмотреть результаты до и после использования параметризации?

Игорь Прищепов

из статьи по ссылке:
"все двойные кавычки, используемые для указания строк, замените на одинарные. Если внутри строки, окруженной двойными кавычками, ранее были одинарные, их нужно продублировать."


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

Вопрос: при конвертации из старых версий автоматически конвертятся тексты запросов в сценариях и обработчиках в соответствие с выбранной моделью параметризации?


 

Игорь Прищепов: обновлено 13.04.2017 в 17:30
Михаил Извеков

Автоматически не конвертятся, т.к. нельзя достоверно определить, SQL запрос это или просто очень похожий на него текст (особенно, когда запросы собирают по кусочкам, эти кусочки передают через функции, сохраняют в окружении и т.п.). Но все подозрительные места можно выловить при поиске несовместимостей, описанном в статье.

Алексей Зубин

Игорь, в любом случае в будущих версиях все эти стандарты помечены как deprecated, т.е. рано или поздно необходимо будет приводить всю прикладную в порядок.

Даже, если сейчас считаете, что вам это не нужно, то писать новую прикладную нужно в соответствии с новыми стандартами соединения, это упростит переход в будущем.

Дмитрий Чепель
Вот это настораживает сразу же. что то я боюсь например. очень боюсь. много где используются строковые значения внутри запросов и в двойных они там или в одинарных - не помнится уже.

Именно поэтому переход на modern-серверную часть сделан опциональным. Если вы останетесь на старой (по умолчанию) - при конвертации ничего делать не нужно

Дмитрий Чепель: обновлено 08.05.2017 в 14:19

Вы пишите, что в коробке уже всё сделано "Стандартная поставка DIRECTUM 5.4 полностью соответствует рекомендациям и не содержит несовместимостей.". НО как тогда объяснить, что после конвертации Я вижу "Предупреждения" в коробочных отчетах?

Привожу часть строк из файла ISBLConverterReport.txt:

Текущая разработка Интегрированные отчеты, расчет Links РКК 5 Текст Предупреждение Неподдерживаемый объект IS-Builder 7.55 ANSI_NULLS ON возможно несовместимый код Действующий MAX_LEVEL = 100 NULL_STR = 'NULL' // Создать список ИД наших организаций

Текущая разработка Интегрированные отчеты, расчет Links РКК 82 Текст Предупреждение Неподдерживаемый объект IS-Builder 7.55 CONCAT_NULL_YIELDS_NULL ON возможно несовместимый код Действующий Level + 1, Way + ', ' + cast(links.RKK2 as varchar(max)) from dbo.MBAnalit links

Текущая разработка Интегрированные отчеты, расчет Links РКК 82 Текст Предупреждение Неподдерживаемый объект IS-Builder 7.55 CONCAT_NULL_YIELDS_NULL ON возможно несовместимый код Действующий Level + 1, Way + ', ' + cast(links.RKK2 as varchar(max)) from dbo.MBAnalit links

Текущая разработка Интегрированные отчеты, расчет Links РКК 89 Текст Предупреждение Неподдерживаемый объект IS-Builder 7.55 CONCAT_NULL_YIELDS_NULL ON возможно несовместимый код Действующий links.Vid = %0:s -- СРК and Parent.Way not like '%%' + cast(links.RKK as varchar(max)) + '%%' )

Текущая разработка Интегрированные отчеты, расчет Links РКК 133 Текст Предупреждение Неподдерживаемый объект IS-Builder 7.55 CONCAT_NULL_YIELDS_NULL ON возможно несовместимый код Действующий 0, -- Признак необходимости отрисовки узла '%1:s, ' + cast(rrc.Analit as varchar(max)) -- Сформировать список обработанных РКК from dbo.MBAnalit links -- СРК

Текущая разработка Интегрированные отчеты, расчет Links РКК 154 Текст Предупреждение Неподдерживаемый объект IS-Builder 7.55 CONCAT_NULL_YIELDS_NULL ON возможно несовместимый код Действующий 0, -- Признак необходимости отрисовки узла parent.Way + ', ' + cast(rrc.Analit as varchar(max)) -- Сформировать список обработанных РКК from dbo.MBAnalit links -- СРК

Текущая разработка Интегрированные отчеты, расчет Links РКК 165 Текст Предупреждение Неподдерживаемый объект IS-Builder 7.55 CONCAT_NULL_YIELDS_NULL ON возможно несовместимый код Действующий -- Не выводить узлы дерева, которые образуют петли --and parent.Way not like '%%, ' + cast(rrc.Analit as varchar(max)) + '%%' and parent.Way not like '%%' + cast(links.RKK as varchar(max)) + '%%' + cast(links.RKK as varchar(max)) + '%%' )

Текущая разработка Интегрированные отчеты, расчет Links РКК 166 Текст Предупреждение Неподдерживаемый объект IS-Builder 7.55 CONCAT_NULL_YIELDS_NULL ON возможно несовместимый код Действующий --and parent.Way not like '%%, ' + cast(rrc.Analit as varchar(max)) + '%%' and parent.Way not like '%%' + cast(links.RKK as varchar(max)) + '%%' + cast(links.RKK as varchar(max)) + '%%' ) -- Добавить узлы дерева РКК во временную таблицу

Текущая разработка Интегрированные отчеты, расчет Links РКК 166 Текст Предупреждение Неподдерживаемый объект IS-Builder 7.55 CONCAT_NULL_YIELDS_NULL ON возможно несовместимый код Действующий --and parent.Way not like '%%, ' + cast(rrc.Analit as varchar(max)) + '%%' and parent.Way not like '%%' + cast(links.RKK as varchar(max)) + '%%' + cast(links.RKK as varchar(max)) + '%%' ) -- Добавить узлы дерева РКК во временную таблицу

 

Текущая разработка Папки поиска, событие На исполнение 10 До выбора Предупреждение Неподдерживаемый объект IS-Builder 7.55 QUOTED_IDENTIFIER ON несовместимый код 'ass.Vid = %s '& 'and subass.YesNo5 = "Д" '& 'and ass.IntNumber3 = Tasks.XRecID)'; References.RRCAssignments.ID)

Текущая разработка Папки поиска, событие На исполнение 10 До выбора Предупреждение Неподдерживаемый объект IS-Builder 7.55 QUOTED_IDENTIFIER ON несовместимый код 'ass.Vid = %s '& 'and subass.YesNo5 = "Д" '& 'and ass.IntNumber3 = Tasks.XRecID)'; References.RRCAssignments.ID)

Текущая разработка Управляемые папки, событие ВХ. На исполнение (для руководителей) Д000003 10 До выбора Предупреждение Неподдерживаемый объект IS-Builder 7.55 QUOTED_IDENTIFIER ON несовместимый код Действующий 'ass.Vid = %s '& 'and subass.YesNo5 = "Д" '& 'and ass.IntNumber3 = Tasks.XRecID)'; References.RRCAssignments.ID)

Текущая разработка Управляемые папки, событие ВХ. Делегированные поручения (для руководителей) Д000005 10 До выбора Предупреждение Неподдерживаемый объект IS-Builder 7.55 QUOTED_IDENTIFIER ON несовместимый код Действующий 'ass.Vid = %s '& 'and subass.YesNo5 = "Д" '& 'and ass.IntNumber3 = Tasks.XRecID)'; References.RRCAssignments.ID)

Текущая разработка Управляемые папки, событие ВХ. На контроле Д000008 20 До выбора Предупреждение Неподдерживаемый объект IS-Builder 7.55 QUOTED_IDENTIFIER ON возможно несовместимый код Действующий Criteria = Sender.SearchCriteria Criteria.AddWhere = Format('(Tasks.StandardRoute in (%s) or (Tasks.State = "C" and Tasks.WorkflowRouteType = "S"))'; RoutesID.DelimitedText)

Текущая разработка Управляемые папки, событие ВХ. На контроле Д000008 20 До выбора Предупреждение Неподдерживаемый объект IS-Builder 7.55 QUOTED_IDENTIFIER ON возможно несовместимый код Действующий Criteria = Sender.SearchCriteria Criteria.AddWhere = Format('(Tasks.StandardRoute in (%s) or (Tasks.State = "C" and Tasks.WorkflowRouteType = "S"))'; RoutesID.DelimitedText)

Дмитрий Чепель

Константин, ответ на ваш вопрос:
1. Конвертер, который достоверно бы находил несовместимости с опциями соединения, сложно реализовать по двум причинам:
- код SQL-запросов на ISBL в большинстве случаев собирается динамически, поэтому мы анализируем похожие на части SQL-запросов части ISBL-текстов
- даже если бы мы анализировали полноценные SQL-запросы, статическим анализом текста понять, например, несовместимость CONCAT_NULL_YIELDS_NULL весьма тяжело
Поэтому конвертер показывает много "возможно несовместимого кода", который по факту совместим.

2. "QUOTED_IDENTIFIER ON несовместимый код":
- "Папки поиска, событие На исполнение" не относится к стандартной разработке DIRECTUM. Вероятно, это папки, созданные непосредственно в вашей системе, вычисления надо исправить вручную.
- "Управляемые папки, событие..." относится к стандартной разработке DIRECTUM, но с версии 5.4 данные папки были заменены на другие. Подробнее см. инструкцию по конвертации "Этап 6. Настройка системы после конвертации -> Конвертация с версии DIRECTUM 5.3.1". Тут либо надо поправить вычисления в папках вручную, либо заменить их согласно инструкции.

3. Основную разработку и тестирование системы DIRECTUM, начиная с версии 5.4, мы ведем на modern-серверной части. Новые инсталляции системы разворачиваются с серверной частью modern. Соответственно, несовместимостей в стандартной поставке DIRECTUM быть не должно.

Дмитрий, спасибо за ответ. Думаю, что нужно учитывать рекомендации написания запросов как для modern и пока оставаться на classic. 

Иван Фатеев

А что насчет ANSI_NULLS? После конвертации станданртные тексты уже подрузмевают, что если сравнение будет с нулем, то ничего не вернется? Или всю араву предупреждений, что выдал конвертер, нужно руками править перед переходом на Modern?

Авторизуйтесь, чтобы написать комментарий