Поле _Active в регистрах

Модератор: Дмитрий Юхтимовский

Поле _Active в регистрах

Сообщение sevushka » 23 окт 2020, 11:29

Добрый день, уважаемые.

В 1с есть стандартный реквизит для регистров, активность. По умолчанию, оно есть в каждом регистре, но его нет в индексах данного регистра. Средствами 1С добавить в индекс поле "Активность" тоже нельзя.
В итоге, при формировании запроса по регистрам накопления, поле _Active используется в условиях, даже если я к нему не обращаюсь в тексте запроса (и это нормально).
Текст запроса (просто для примера, может быть любым)
Код: выделить все
ВЫБРАТЬ
   ВСО.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
   СУММА(ВСО.СуммаВыручкиОборот) КАК Оборот
ИЗ
   РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&ДатаНач, &ДатаКон, , АналитикаУчетаНоменклатуры.Номенклатура = &Номенклатура) КАК ВСО

СГРУППИРОВАТЬ ПО
   ВСО.АналитикаУчетаНоменклатуры.Номенклатура


превращается в запрос
Код: выделить все
SELECT
T4._Fld3883RRef,
CAST(SUM(T1.Fld21010Turnover_) AS NUMERIC(27, 2))
FROM (SELECT
T2._Fld20995RRef AS Fld20995RRef,
CAST(SUM(T2._Fld21010) AS NUMERIC(21, 2)) AS Fld21010Turnover_
FROM dbo._AccumRg20994 T2
LEFT OUTER JOIN dbo._Reference144 T3
ON (T2._Fld20995RRef = T3._IDRRef) AND (T3._Fld960 = @P1)
WHERE ((T2._Fld960 = @P2)) AND (T2._Period >= @P3 AND T2._Period <= @P4 AND T2._Active = 0x01 AND ((T3._Fld3883RRef = @P5)))
GROUP BY T2._Fld20995RRef
HAVING (CAST(SUM(T2._Fld21010) AS NUMERIC(21, 2))) <> 0.0) T1
LEFT OUTER JOIN dbo._Reference144 T4
ON (T1.Fld20995RRef = T4._IDRRef) AND (T4._Fld960 = @P6)
GROUP BY T4._Fld3883RRef


Обращаю внимание на условие AND T2._Active = 0x01
Соответственно - в плане есть бесполезный кусок
Код: выделить все
|--Clustered Index Seek(OBJECT:([View_Backup].[dbo].[_AccumRg20994].[_AccumRg20994_ByPeriod] AS [T2]), SEEK:([T2].[_Fld960]=[View_Backup].[dbo].[_AccumRg20994].[_Fld960] as [T2].[_Fld960] AND [T2].[_Period]=[View_Backup].[dbo].[_AccumRg20994].[_Period] as [T2].[_Period] AND [T2].[_RecorderTRef]=[View_Backup].[dbo].[_AccumRg20994].[_RecorderTRef] as [T2].[_RecorderTRef] AND [T2].[_RecorderRRef]=[View_Backup].[dbo].[_AccumRg20994].[_RecorderRRef] as [T2].[_RecorderRRef] AND [T2].[_LineNo]=[View_Backup].[dbo].[_AccumRg20994].[_LineNo] as [T2].[_LineNo]),  WHERE:([View_Backup].[dbo].[_AccumRg20994].[_Active] as [T2].[_Active]=0x01) LOOKUP ORDERED FORWARD)


Понимаю, что этот вопрос больше к фирме 1С, но мне хочется понимать, как с этим борются другие программисты?
Только добавлять средствами SQL в нужные индексы поле _Active, и плевать на то, что 1с это запрещает?
И нельзя сказать что это поле не нужно, у меня скуль говорит, что добавление __Active в индекс дает [dbo].[_AccumRg20994] Est. benefit per day: 4,444,739, [dbo].[_AccumRg21497] Est. benefit per day: 3,880,278
и таких строк - десятки, по многим регистрам.

Я не скажу, что там огромный выигрыш, там процентов 7-11 получается на тех запросах, которые я смотрел...(это без учета того, что запись будет медленнее из-за индексов) Просто - почему 1С это не делают сами, по умолчанию? В чем могут быть подводные камни?
sevushka
 
Сообщений: 70
Зарегистрирован: 18 фев 2013, 07:45

Re: Поле _Active в регистрах

Сообщение Дмитрий Юхтимовский » 23 окт 2020, 18:32

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

Ну или активней используйте итоги и агрегаты.
Дмитрий Юхтимовский
 
Сообщений: 649
Зарегистрирован: 11 фев 2013, 19:28
Откуда: gilev.ru

понятен ли вопрос?

Сообщение Гилёв Вячеслав » 28 окт 2020, 12:20

sevushka писал(а): В чем могут быть подводные камни?

какова селективность по этому полю?

чем больше записей выдается по индексу с полем _Active, тем хуже селективность и вероятность использования такого индекса
идеальная селективность, когда отбор по полю выдает 1 запись
Гилёв Вячеслав
 
Сообщений: 2303
Зарегистрирован: 11 фев 2013, 15:40
Откуда: Россия, Москва

Re: Поле _Active в регистрах

Сообщение Дмитрий Юхтимовский » 28 окт 2020, 13:17

селективность по данному полю отвратительная, в большинстве таблиц подобного вида она будет возвращать условно 99% объёма таблицы, SQL такие индексы будет пытаться игнорировать при любой возможности.
Дмитрий Юхтимовский
 
Сообщений: 649
Зарегистрирован: 11 фев 2013, 19:28
Откуда: gilev.ru

Re: Поле _Active в регистрах

Сообщение Гилёв Вячеслав » 29 окт 2020, 13:04

Дим, я же не тебя спрашивал )
Гилёв Вячеслав
 
Сообщений: 2303
Зарегистрирован: 11 фев 2013, 15:40
Откуда: Россия, Москва

Re: понятен ли вопрос?

Сообщение sevushka » 30 окт 2020, 06:07

Гилёв Вячеслав писал(а):какова селективность по этому полю?


Так, мой вопрос не поняли. Совершенно не поняли. Попробую еще раз.
Я прекрасно понимаю, что (в моих примерах) поле _Active ВСЕГДА 0x01. Во всех десятках миллионов записей.

НО!!!
Вариант 1. Как сделано сейчас, _Active в индексе нет, так сделано 1С.
Шаг 1. Из регистра ххх по индексу ххх_ByPeriod вытаскивается 500к записей по условию период >=@P1 и период <=@P2
Шаг 2. Эти 500к записей прогоняются по самому регистру, проверяется поле _Active = 0x01, НИЧЕГО не меняется, те же 500к записей идут дальше. Этот шаг стоит определенных действий, выражающихся в reads, и как следствие - querybucks. Ну и время, что понятно.

Вариант 2. Вручную добавляем поле с отвратительной селективностью _Active в имеющийся регистр ххх_ByPeriod. Последним полем. (нарушая лицензии 1с, понимая, что это слетит при переиндексации, ТИИ и пр.). В итоге получаем:
Шаг 1. Из регистра ххх по индексу ххх_ByPeriod вытаскивается 500к записей по условию период >=@P1 и период <=@P2 и _Active = 0x01. Стоит это почти столько же, сколько шаг1 в первом варианте (на чуть-чуть больше reads, т.к. индекс стал больше на одно _Active (binary, 1) поле).
Шага 2 - НЕТ.
И в НЕКОТОРЫХ запросах отсутствие этого Шаг2 дает до 10% ускорение по времени. Замедление записи в регистр от добавления лишнего поля в индекс я не смог измерить, оно мало.

Где ошибка в моих рассуждениях? Почему поле _Active используют в Where, но не добавляют в индексы?
sevushka
 
Сообщений: 70
Зарегистрирован: 18 фев 2013, 07:45

Re: Поле _Active в регистрах

Сообщение Гилёв Вячеслав » 30 окт 2020, 15:14

предполагается видимо что активность больше ценна для документ, и документы без активности движений не рисуют
вы не с того начала, начните с решаемой задачи: вам что нужно отоборать записи с _Active = ложь?
Гилёв Вячеслав
 
Сообщений: 2303
Зарегистрирован: 11 фев 2013, 15:40
Откуда: Россия, Москва

Re: Поле _Active в регистрах

Сообщение sevushka » 02 ноя 2020, 07:29

Гилёв Вячеслав писал(а):вы не с того начала, начните с решаемой задачи: вам что нужно отоборать записи с _Active = ложь?

Нет.

1. Поступила задача оптимизировать запрос.
2. Оптимизировал, заказчик уже доволен. Но в процессе, работая с планом запроса, увидел два обращения к регистру. Сначала проверяли дату через индекс ByPeriod, потом у отобранных записей проверяли _Active. И так - не по одному запросу и не по одному регистру.
3. Вручную добавил _Active в индекс. Стало быстрее по выполняемому времени, меньше reads, индекс вырос не сильно.
4. Зашел на форум, посвященный производительности 1с (сюда). Спросил, почему _Active не добавляют в индексы по умолчанию. (Думал, что у вас же есть данные по сервису index, туда же по идее тоже должны падать рекомендации по созданию / добавлению _Active в индексы, может уже решали данную проблему с другими)
5. Понял, что всем на это пофиг. ОК, буду копать сам, в свободное время.
sevushka
 
Сообщений: 70
Зарегистрирован: 18 фев 2013, 07:45

Re: Поле _Active в регистрах

Сообщение Дмитрий Юхтимовский » 02 ноя 2020, 10:53

Тут не "всем на это пофиг", но поле это есть в массе таблиц, запросы к нему идут постоянно, а во все нужные индексы добавлять и его (и не забывать отслеживать, если оно исчезло из индекса в результате реструктуризации) видится чересчур накладным, поэтому проблему лучше решать "в консерватории", то есть решать вопрос по возможности без самопальных индексов.
Дмитрий Юхтимовский
 
Сообщений: 649
Зарегистрирован: 11 фев 2013, 19:28
Откуда: gilev.ru

Re: Поле _Active в регистрах

Сообщение Гилёв Вячеслав » 02 ноя 2020, 13:25

sevushka писал(а):
Гилёв Вячеслав писал(а):вы не с того начала, начните с решаемой задачи: вам что нужно отоборать записи с _Active = ложь?

Нет.

1. Поступила задача оптимизировать запрос.
то что мы говорим об оптимизации запроса и так было понятно
не понято в рамках запросах что конкретно вам надо было сделать относительно _Active
если отобрать как я предположил (вы кстати так и не ответили), то такой отбор должен происходить вероятно в последнюю очередь, после того как будут наложены все более строгие отборы, а если это будет на выходе из подзапросов где останется сотня строк (в нормальных планах в конце не должно оставаться их миллионами) то там индекс уже будет не нужен
Гилёв Вячеслав
 
Сообщений: 2303
Зарегистрирован: 11 фев 2013, 15:40
Откуда: Россия, Москва


Вернуться в Осуждаем проблемы производительности 1с

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1