Кордон і момент часу - це прикладні об'єкти, які є комбінацією дати і ряду інших параметрів, які дозволяють вказати системі точну межу отримання даних з таблиць регістрів.
Наприклад, частою ситуацією є наявність декількох документів в рамках однієї секунди - в цьому випадку, розробники використовують позицію документа для правильного отримання залишків в обробках проведення, тому що при використанні просто дати дані можуть бути некоректними.
Але при цьому використання Межі і МоментаВремені може погіршити продуктивність, уповільнивши виконання навіть елементарних запитів до віртуальних таблиць.
Розглянемо конкретний приклад.
Візьмемо регістр накопичення "ПартііТоваровНаСкладах" і отримаємо з нього залишки з відбором по цій Класифікації і Складу.
(У тимчасових таблицях з номенклатурою і складами значень трохи)
Є додатковий індекс по вимірюванню Склад.
Виконуємо запит з різним значенням параметра "період":
Виконуємо ці запити кілька разів і отримуємо такі результати:
Заміри зроблені для 3х різних значень "Max Degree of Parallelism" сервера MSSQL.
Є різні думки з приводу параметра MAXDOP. 1С-ники частіше схиляються до встановлення одиниці. А ось, наприклад, думка DBA, які адмініструють інші види додатків :).
Але питання в іншому.
У всіх 4х випадках платформа генерує приблизно однакові запити з двома частинами:
Кінцевий залишок виходить різницею цих двох таблиць.
З вибіркою підсумків в частині швидкодії все добре - в таблиці є кластерний індекс з усіма вимірами, для якого умови запиту добре підходять.
А ось з вибіркою з таблиці рухів явно є проблема.
Для умови з позицією документа запит має вигляд:
Для умови з датою запит має вигляд:
Явно в першому випадку запит більш складний для сприйняття оптимізатором.
Винесемо обидва підзапиту в SQL Server management Studio і подивимося як вони виконуються:
Статистика введення / виведення і тривалість виконання:
Перший запит (з позицій по документу) виконався в 4,5 рази довше другого і зажадав у 8 разів більше логічних читань.
Структура ідентична, але використовувані параметри різні.
Для першого запиту Seek Predicate вказано тільки один (період менше 1 травня), а для другого - обидва обмеження по періоду.
Варіант вирішення проблеми:
Якщо проблема у вас підтверджується, то бажано по максимуму відмовитися від використання Межі і МоментаВремені при відборі по періоду в запитах до віртуальних таблиць. Якщо подібний запит є в процедурі проведення документа, то відбір залишків по позиції документа потрібен не завжди, а тільки тоді, коли документ НЕ є першим в секунді і документи впливають один на одного. Залежно від інтенсивності документообігу, це може істотно знизити кількість запитів з небажаними параметрами.
Наприклад, під час запису документа контролювати - чи є записи в регістрі в даній секунді раніше поточного документа за таким же Складу. Якщо немає, то відбирати залишки за датою, якщо так - по позиції документа:
При цьому варіант спрощення запиту з позицією документа, який дозволить усунути цю проблему, існує. На жаль, зробити це можуть тільки розробники платформи.
Я описав цю ситуацію і варіант оптимізації в партнерській конференції.
У кого є доступ - буду вдячний за "+1" в тій темі.