Имя: Пароль:
1C
1С v8
Долгое выполнение запроса
0 Cumpuciy
 
22.03.12
12:34
Торговля 10.2
Платформа 8.2.13.213
Пользователи стали жаловаться на периодические Конфликты блокировок.
Выяснилось, что конфликты возникают, когда кто-нибудь оперативно проводит заказ покупателя. А ещё конкретнее дело в регистре товары в резерве на складах.
В модуле набора записей есть процедура КонтрольСвободныхОстатков, вот в ней выполняется запрос, с блокировкой данных. Запрос выполняется неприлично долго, особенно когда в заказе большое количество номенклатуры. Т.к. в запросе есть
|ДЛЯ ИЗМЕНЕНИЯ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки // Блокирующие чтение таблицы остатков регистра для разрешения коллизий многопользовательской работы
Во время его выполнения количество заблокированных данных, судя по консоли, постоянно растет. У остальных пользователей появляются конфликты блокировок.
Сам запрос:
ВЫБРАТЬ
   Док.Номенклатура КАК Номенклатура,
   Док.Номенклатура.ЕдиницаХраненияОстатков КАК ЕдиницаХраненияОстатков,
   Док.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
   Док.Размещение КАК Склад,
   СУММА(Док.Количество * Док.Коэффициент / Док.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент) КАК ДокументКоличество,
   0 КАК КолСнятиеРазмещений,
   МАКСИМУМ(Резервы.КоличествоОстаток) КАК РезервыКоличество,
   МАКСИМУМ(Остатки.КоличествоОстаток) КАК ОстаткиКоличество,
   МАКСИМУМ(КПередаче.КоличествоОстаток) КАК КПередачеКоличество
ИЗ
   Документ.ЗаказПокупателя.Товары КАК Док
       ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(
               ,
               Номенклатура В
                   (ВЫБРАТЬ РАЗЛИЧНЫЕ
                       Документ.ЗаказПокупателя.Товары.Номенклатура
                   ИЗ
                       Документ.ЗаказПокупателя.Товары
                   ГДЕ
                       Документ.ЗаказПокупателя.Товары.Ссылка = &ДокументСсылка)) КАК Остатки
       ПО Док.Номенклатура = Остатки.Номенклатура
           И Док.Размещение = Остатки.Склад
           И Док.ХарактеристикаНоменклатуры = Остатки.ХарактеристикаНоменклатуры
       ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(
               ,
               Номенклатура В
                   (ВЫБРАТЬ РАЗЛИЧНЫЕ
                       Документ.ЗаказПокупателя.Товары.Номенклатура
                   ИЗ
                       Документ.ЗаказПокупателя.Товары
                   ГДЕ
                       Документ.ЗаказПокупателя.Товары.Ссылка = &ДокументСсылка)) КАК Резервы
       ПО Док.Номенклатура = Резервы.Номенклатура
           И Док.Размещение = Резервы.Склад
           И Док.ХарактеристикаНоменклатуры = Резервы.ХарактеристикаНоменклатуры
       ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыКПередачеСоСкладов.Остатки(
               ,
               Номенклатура В
                   (ВЫБРАТЬ РАЗЛИЧНЫЕ
                       Документ.ЗаказПокупателя.Товары.Номенклатура
                   ИЗ
                       Документ.ЗаказПокупателя.Товары
                   ГДЕ
                       Документ.ЗаказПокупателя.Товары.Ссылка = &ДокументСсылка)) КАК КПередаче
       ПО Док.Номенклатура = КПередаче.Номенклатура
           И Док.Размещение = КПередаче.Склад
           И Док.ХарактеристикаНоменклатуры = КПередаче.ХарактеристикаНоменклатуры
ГДЕ
   Док.Ссылка = &ДокументСсылка
   И Док.Размещение ССЫЛКА Справочник.Склады

СГРУППИРОВАТЬ ПО
   Док.Номенклатура,
   Док.Номенклатура.ЕдиницаХраненияОстатков,
   Док.ХарактеристикаНоменклатуры,
   Док.Размещение
ДЛЯ ИЗМЕНЕНИЯ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки
Даже когда выполняю этот запрос с каким нибудь заказом в консоли отчетов без Для Изменения, выполняется очень долго. И в консоли заблокировано субд растет.
Появилось это внезапно. В какую сторону копать?
Спасибо, подскажите.
1 Мыш
 
22.03.12
12:35
(0) Пересчет итогов, реиндексация, дефрагментирование.
2 Мыш
 
22.03.12
12:36
Плюс железо проверить. Вдруг винты рушатся или контроллер глючит.
3 Мыш
 
22.03.12
12:36
> Появилось это внезапно
Аргумент в сторону предположения о железе.
4 Kashemir
 
22.03.12
12:44
Да можно начать и с оптимизации запроса.

К примеру вот эту таблицу я бы вынес во временную и проиндексировал

ВЫБРАТЬ РАЗЛИЧНЫЕ
                       Документ.ЗаказПокупателя.Товары.Номенклатура
                   ИЗ
                       Документ.ЗаказПокупателя.Товары
                   ГДЕ
                       Документ.ЗаказПокупателя.Товары.Ссылка = &ДокументСсылка
5 Kashemir
 
22.03.12
12:45
+ В остатках неплохо бы период указать
6 Cumpuciy
 
22.03.12
12:47
На тестовой базе с идентичной конфигурацией и данными, актуальными на неделю раньше все летает.
(1) итоги пересчитаю, переиндексировал недавно, может с этим связано.
(4) эта конструкция мне тоже совсем не нравится, но опять же на тестовой базе все ок.
Я вот грешу на SQL базу.
7 Kashemir
 
22.03.12
12:48
Кроме того сам код должен предусматривать обращение на чтение максимально близко к финалу обработки проведения - дабы уменьшить время блокировки таблиц в транзакции проведения.
8 Cumpuciy
 
22.03.12
12:49
Это часть стандартного кода УТ, ничего не менялось.
Именно этот запрос занимает 90% времени обработки проведения.
9 Cumpuciy
 
22.03.12
12:49
Вся обработка проведения стандартная.
10 Kashemir
 
22.03.12
12:49
(6) Грешить на SQL конечно можно, ибо в данном случае возможно выбирается неотимальный план запросов. И твоя задача как программиста, помочь SQL с определением оптимального плана запроса. Использование временных таблиц в данном случае более чем оправдано.
11 Axel2009
 
22.03.12
12:52
(0) чаша переполнилась и начались тормоза
12 Cumpuciy
 
22.03.12
12:55
(11) не думаю, что вот так вот за пару недель переполнилась.
(10) попробую
13 ptrtss
 
22.03.12
13:08
Коллеги, а вот так

МАКСИМУМ(Резервы.КоличествоОстаток)


делать разве можно? В этом регистре же еще другие измерения есть, кроме тех по которым идет соединение. Или виртуальная таблица при присоединении по неполному набору измерений сама сворачивается?
14 Kashemir
 
22.03.12
13:11
(13) Не сворачивается, наверно неочевидная для нас логика не предусматривает использования множества значений неиспользуемых измерений :)
15 Kashemir
 
22.03.12
13:11
(0) Попробуй для начала так

ВЫБРАТЬ
   Док.Номенклатура КАК Номенклатура,
   Док.Номенклатура.ЕдиницаХраненияОстатков КАК ЕдиницаХраненияОстатков,
   Док.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
   Док.Размещение КАК Склад,
   СУММА(Док.Количество * Док.Коэффициент / Док.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент) КАК ДокументКоличество
ПОМЕСТИТЬ ТЧДокумента
ИЗ
   Документ.ЗаказПокупателя.Товары КАК Док
ГДЕ
   Док.Ссылка = &ДокументСсылка
   И Док.Размещение ССЫЛКА Справочник.Склады

СГРУППИРОВАТЬ ПО
   Док.Номенклатура,
   Док.Номенклатура.ЕдиницаХраненияОстатков,
   Док.ХарактеристикаНоменклатуры,
   Док.Размещение

ДЛЯ ИЗМЕНЕНИЯ

ИНДЕКСИРОВАТЬ ПО
   Номенклатура,
   Склад,
   ХарактеристикаНоменклатуры
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ТЧДокумента.Номенклатура КАК Номенклатура,
   ТЧДокумента.ЕдиницаХраненияОстатков КАК ЕдиницаХраненияОстатков,
   ТЧДокумента.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
   ТЧДокумента.Склад КАК Склад,
   СУММА(ТЧДокумента.ДокументКоличество) КАК ДокументКоличество,
   0 КАК КолСнятиеРазмещений,
   МАКСИМУМ(Резервы.КоличествоОстаток) КАК РезервыКоличество,
   МАКСИМУМ(Остатки.КоличествоОстаток) КАК ОстаткиКоличество,
   МАКСИМУМ(КПередаче.КоличествоОстаток) КАК КПередачеКоличество
ИЗ
   ТЧДокумента КАК ТЧДокумента
       ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(
               ,
               Номенклатура В
                   (ВЫБРАТЬ РАЗЛИЧНЫЕ
                       ТЧДокумента.Номенклатура
                   ИЗ
                       ТЧДокумента КАК ТЧДокумента)) КАК Остатки
       ПО ТЧДокумента.Номенклатура = Остатки.Номенклатура
           И ТЧДокумента.Склад = Остатки.Склад
           И ТЧДокумента.ХарактеристикаНоменклатуры = Остатки.ХарактеристикаНоменклатуры
       ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(
               ,
               Номенклатура В
                   (ВЫБРАТЬ РАЗЛИЧНЫЕ
                       ТЧДокумента.Номенклатура
                   ИЗ
                       ТЧДокумента КАК ТЧДокумента)) КАК Резервы
       ПО ТЧДокумента.Номенклатура = Резервы.Номенклатура
           И ТЧДокумента.Склад = Резервы.Склад
           И ТЧДокумента.ХарактеристикаНоменклатуры = Резервы.ХарактеристикаНоменклатуры
       ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыКПередачеСоСкладов.Остатки(
               ,
               Номенклатура В
                   (ВЫБРАТЬ РАЗЛИЧНЫЕ
                       ТЧДокумента.Номенклатура
                   ИЗ
                       ТЧДокумента КАК ТЧДокумента)) КАК КПередаче
       ПО ТЧДокумента.Номенклатура = КПередаче.Номенклатура
           И ТЧДокумента.Склад = КПередаче.Склад
           И ТЧДокумента.ХарактеристикаНоменклатуры = КПередаче.ХарактеристикаНоменклатуры

СГРУППИРОВАТЬ ПО
   ТЧДокумента.Номенклатура,
   ТЧДокумента.ЕдиницаХраненияОстатков,
   ТЧДокумента.ХарактеристикаНоменклатуры,
   ТЧДокумента.Склад

ДЛЯ ИЗМЕНЕНИЯ
   РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки
16 ptrtss
 
22.03.12
13:13
(14) Кхм... Я вот глянул щас, там есть например ДокументРезерва. И причем это стандартный код 1С, стало быть на всю страну должен быть рассчитан. Сдается мне он кривой. Все остатки во временные таблицы и сворачивать по трем измерениям каждую перед употреблением
17 Kashemir
 
22.03.12
13:14
(16) Ну по хорошему то оно так. Но ТС вроде жалуется на скорость запроса, а не его некорректность.
18 Cumpuciy
 
22.03.12
13:14
(15)в консоли мгновенно выполнил.
19 ptrtss
 
22.03.12
13:15
(17) Ну, это чтоб ему две темы не создавать, оптом ткскть
20 Kashemir
 
22.03.12
13:15
(18) Ну и чудно - значит проблема решена.
21 hhhh
 
22.03.12
13:15
(13) сворачивает по тем измерениям, которых нет в запросе. То есть

    ПО Док.Номенклатура = Остатки.Номенклатура
           И Док.Размещение = Остатки.Склад
           И Док.ХарактеристикаНоменклатуры = Остатки.ХарактеристикаНоменклатуры
 

по измерениям Номенклатура, Склад и Характеристика не должно сворачивать
22 ptrtss
 
22.03.12
13:17
(21) Прям искусственный интеллект!))
23 Kashemir
 
22.03.12
13:17
(21) Да данные регистра то оно свернет, а вот ДокументКоличество при этом может задвоится/троицо и т.д.
24 hhhh
 
22.03.12
13:19
(23) в данном случае не двоит. То есть задвоит не виртуальная таблица, а

СГРУППИРОВАТЬ ПО
25 ptrtss
 
22.03.12
13:19
(23) по идее, если уж сворачивать, то на этапе формирования виртуальной таблицы
26 ptrtss
 
22.03.12
13:20
+(25) не должно двоить типо, как свернутая временная таблица должно работать
27 Cumpuciy
 
22.03.12
13:21
Я так понимаю временную таблицу ТЧДокумента нужно потом уничтожить после выполнения запроса
28 Kashemir
 
22.03.12
13:23
(27) Не парься - ничего уничтожать не нужно, если не используеш менеджервременныхтаблиц или пакетного выполнения запроса.
29 Kashemir
 
22.03.12
13:25
+(28) Хотя при пакетном выполнении тоже можно не заморачиваться. Таблица будет жить только в случае живого менеджера временных файлов запроса.
30 Cumpuciy
 
22.03.12
13:25
ок.спасибо.
На рабочей базе запрос работает быстрее. На тестовой - одинаково со старым. Т.е. одинаково быстро.
31 Kashemir
 
22.03.12
13:27
(30) Такой запрос на SQL всегда будет выполнятся одинаково быстро (конечно без учета роста базы) ибо в нем практически не осталось элементов, неоднозначно влияющих на выбор плана запроса
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший