Проблемы и оптимизация динамических списков.

Опубликовал Danil Potapov (Danil.Potapov) в раздел Программирование - Практика программирования

Ядром динамического списка является объект СКД, в публикации продемонстрированы текущие проблемы динамического списка и возможность оптимизации сложных запросов.

Проверял на платоформах: 8.2.17.169, 8.2.18.109

1. Если через изменить форму отключить вывод поля в списке / удалить поле из списка, то платформа все равно будет получать данные по этим полям до тех пор пока вы не перезапустите форму.

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

Пример запроса из profiler:

...

FROM _Document128 T1 WITH(NOLOCK)

LEFT OUTER JOIN _Document128_VT1811 T3 WITH(NOLOCK)
ON ((T3._Document128_IDRRef = T1._IDRRef) AND (T3._Fld1813RRef = @P2))
LEFT OUTER JOIN _Document128_VT1811 T4 WITH(NOLOCK)
ON ((T4._Document128_IDRRef = T1._IDRRef) AND (T4._Fld1813RRef = @P3))
LEFT OUTER JOIN _Document128_VT1811 T5 WITH(NOLOCK)
ON ((T5._Document128_IDRRef = T1._IDRRef) AND (T5._Fld1813RRef = @P3))
LEFT OUTER JOIN _Document128_VT1811 T6 WITH(NOLOCK)
ON ((T6._Document128_IDRRef = T1._IDRRef) AND (T6._Fld1813RRef = @P2))
LEFT OUTER JOIN _Reference69_VT781 T7 WITH(NOLOCK)

...

 

3.1 При использовании языка расширения запросов СКД для указания необязательных таблиц платформа игнорирует эти указания.

ВЫБРАТЬ

               Док.Ссылка,

               ТЧ.Значение

ИЗ

               Документ.ЗаказКлиента КАК Док

                              {ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента.ДополнительныеРеквизиты КАК ТЧ

                              ПО (ТЧ.Ссылка = Док.Ссылка)

                                              И (ТЧ.Свойство = ЗНАЧЕНИЕ(ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПустаяСсылка))}

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

3.2 Более того, поля добавленные в таблицу через конфигуратор и отключенные через команду "изменить форму" никогда не исключаются из результирующего запроса к базе данных (такие поля еще нельзя удалить из спика).

Из пункта 3.1 и 3.2 следует, что если вы захотите ускорить вывод данных в списке путем отключения ненужных полей, то по факту никакой оптимизации не произойдет. Пример: посмотрите запрос динамического списка в УТ 11 в форме ФормаСпискаДокументов докумена заказ клиента . При отключении вывода множества расчетных полей оптимизации не произойдет. 


4. Для того, что сработал отбор в параметрах виртуальной таблицы требуется указывать псевдоними полей, пример:

ВЫБРАТЬ
Спр.Ссылка КАК Ссылка,
РН.ВНаличииОстаток,
РН.ВРезервеОстаток
ИЗ
Справочник.Номенклатура КАК Спр
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(, {(Номенклатура).* КАК Ссылка}) КАК РН
ПО (РН.Номенклатура = Спр.Ссылка)

 

запрос без псевдонима

SELECT TOP 22
T1._IDRRef,
T2.Fld4965Balance_,
T2.Fld4966Balance_,
T1._Marked,
T1._IsMetadata,
CASE WHEN (T1._Folder = 0x00) THEN 0x01 ELSE 0x00 END,
T1._Description,
T1._Code,
T1._Description
FROM _Reference63 T1 WITH(NOLOCK)
LEFT OUTER JOIN (SELECT
T3._Fld4961RRef AS Fld4961RRef,
CAST(SUM(T3._Fld4965) AS NUMERIC(32, 8)) AS Fld4965Balance_,
CAST(SUM(T3._Fld4966) AS NUMERIC(32, 8)) AS Fld4966Balance_
FROM _AccumRgT4967 T3 WITH(NOLOCK)
WHERE T3._Period = @P1
GROUP BY T3._Fld4961RRef
HAVING (CAST(SUM(T3._Fld4965) AS NUMERIC(32, 8))) <> @P2 OR (CAST(SUM(T3._Fld4966) AS NUMERIC(32, 8))) <> @P2) T2
ON (T2.Fld4961RRef = T1._IDRRef)

 

запрос с псевдонимом

SELECT TOP 22
T5._IDRRef,
T6.Fld4965Balance_,
T6.Fld4966Balance_,
T5._Marked,
T5._IsMetadata,
CASE WHEN (T5._Folder = 0x00) THEN 0x01 ELSE 0x00 END,
T5._Description,
T5._Code,
T5._Description
FROM _Reference63 T5 WITH(NOLOCK)
LEFT OUTER JOIN (SELECT
T7._Fld4961RRef AS Fld4961RRef,
CAST(SUM(T7._Fld4965) AS NUMERIC(32, 8)) AS Fld4965Balance_,
CAST(SUM(T7._Fld4966) AS NUMERIC(32, 8)) AS Fld4966Balance_
FROM _AccumRgT4967 T7 WITH(NOLOCK)
LEFT OUTER JOIN _Reference63 T8 WITH(NOLOCK)
ON T7._Fld4961RRef = T8._IDRRef
WHERE T7._Period = @P1 AND ((T8._Fld7329RRef = @P2))
GROUP BY T7._Fld4961RRef
HAVING (CAST(SUM(T7._Fld4965) AS NUMERIC(32, 8))) <> @P3 OR (CAST(SUM(T7._Fld4966) AS NUMERIC(32, 8))) <> @P3) T6
ON (T6.Fld4961RRef = T5._IDRRef)

При этом будет работать платформенный механизм поиска через "найти",  но не будут работать платформенные отборы:

     - по родителю при иерархии

     - для выборки порции данных (кадр динамического списка)

 

5. Выводите реквизиты объекта в динамический список через поле ссылка, основной запрос пусть будет "ВЫБРАТЬ Ссылка ИЗ ТаблицаОбъекта".

   - Платформа понимает, что не нужно делать  соединение с основной таблицей, если идет конструкция вида Ссылка.Номер

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

    - Будет работать отбор в присоединяемых таблицах, если выполнить пункт 4.

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

 

6. При пролистывании динамического списка с дополнительными реквизитами/свойствами платформа начинает ощутимо подтормаживать, при упорядочивании зависает. 

Здесь есть два решения,

I. отключить вывод дополнительных реквизитов/свойств

{ХАРАКТЕРИСТИКИ
ТИП(Документ.ЗаказКлиента)
ВИДЫХАРАКТЕРИСТИК (ВЫБРАТЬ ПЕРВЫЕ 0
NULL КАК Ключ,
NULL КАК Имя,
NULL КАК ТипЗначения)
ПОЛЕКЛЮЧА Ключ
ПОЛЕИМЕНИ Имя
ПОЛЕТИПАЗНАЧЕНИЯ ТипЗначения
ЗНАЧЕНИЯХАРАКТЕРИСТИК (ВЫБРАТЬ ПЕРВЫЕ 0
NULL КАК Объект,
NULL КАК Вид,
NULL КАК Значение)
ПОЛЕОБЪЕКТА Объект
ПОЛЕВИДА Вид
ПОЛЕЗНАЧЕНИЯ Значение }

II Описать для каждого свойства получение данных и в запросе на выборку данных реализовать получение свойства через ВЫРАЗИТЬ.

Пример:

{ХАРАКТЕРИСТИКИ
ТИП(Документ.ЗаказКлиента)
ВИДЫХАРАКТЕРИСТИК (ВЫБРАТЬ
ПВХ.Ссылка,
ПВХ.Наименование,
ПВХ.ТипЗначения
ИЗ
ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ПВХ
ГДЕ
ПВХ.Ссылка = ЗНАЧЕНИЕ(ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.ОператорДоставки))
ПОЛЕКЛЮЧА Ссылка
ПОЛЕИМЕНИ Наименование
ПОЛЕТИПАЗНАЧЕНИЯ ТипЗначения
ЗНАЧЕНИЯХАРАКТЕРИСТИК (ВЫБРАТЬ
ТЧ.Ссылка,
ТЧ.Свойство,
ВЫРАЗИТЬ(ТЧ.Значение КАК Справочник.ОператорыДоставок) КАК Значение
ИЗ
Документ.ЗаказКлиента.ДополнительныеРеквизиты КАК ТЧ ГДЕ ТЧ.Значение ссылка Справочник.ОператорыДоставок)
ПОЛЕОБЪЕКТА Ссылка
ПОЛЕВИДА Свойство
ПОЛЕЗНАЧЕНИЯ Значение }

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

 

См. также

Комментарии
1. Александр Давыдов (frying) 19 14.08.13 23:46 Сейчас в теме
1,3 - были признаны ошибками платформы и через некоторое время скорее всего уйдут.

В пукте 6, в чем состоит смысл оператора ВЫРАЗИТЬ. Чем он облегчает запрос?
2. Dpotapov (Danil.Potapov) 15.08.13 10:13 Сейчас в теме
(1) frying, Да, пункты 1 - 3 будут исправлены, хорошо, если это будет в 8.2.
по пункту 6 рекомендую:
- http://www.gilev.ru/optimquery/
- http://infostart.ru/public/184361/
- просмотр profiler в момент получения данных, особенно интересно при упорядочивании по характеристике объекта.
Gilev.Vyacheslav; +1 Ответить 1
3. Александр Давыдов (frying) 19 15.08.13 11:13 Сейчас в теме
(2) - просмотр profiler в момент получения данных, особенно интересно при упорядочивании по характеристике объекта.

С какими-то операциями, сортировкой, получением от характеристик "вложенных" значений через точку действительно поможет. А просто при выводе на экран как поможет?
4. Dpotapov (Danil.Potapov) 15.08.13 16:46 Сейчас в теме
5. Александр Давыдов (frying) 19 15.08.13 17:36 Сейчас в теме
(4) Я считаю практически никак, разница в чтении одной или 6-ти колонок.
6. Алексей Кирин (kirinalex) 21.06.14 13:15 Сейчас в теме
по пункту 4
1. что мы улучшаем таким способом? как меняются показатели при замере производительности?
2. что за отбор показан в разделе "запрос с псевдонимом"?
AND ((T8._Fld7329RRef = @P2))
7. Dpotapov (Danil.Potapov) 24.06.14 11:55 Сейчас в теме
(6) kirinalex, если пользователь устанавливает отбор по реквизитам объекта (через найти или через настройку отбора), то система установит отбор в параметрах виртуальных таблиц.