Проблема швидкодії при використанні позиції документа замість дати в віртуальних таблицях

Кордон і момент часу - це прикладні об'єкти, які є комбінацією дати і ряду інших параметрів, які дозволяють вказати системі точну межу отримання даних з таблиць регістрів.
Наприклад, частою ситуацією є наявність декількох документів в рамках однієї секунди - в цьому випадку, розробники використовують позицію документа для правильного отримання залишків в обробках проведення, тому що при використанні просто дати дані можуть бути некоректними.
Але при цьому використання Межі і МоментаВремені може погіршити продуктивність, уповільнивши виконання навіть елементарних запитів до віртуальних таблиць.

Розглянемо конкретний приклад.

Візьмемо регістр накопичення "ПартііТоваровНаСкладах" і отримаємо з нього залишки з відбором по цій Класифікації і Складу.

Проблема швидкодії при використанні позиції документа замість дати в віртуальних таблицях

(У тимчасових таблицях з номенклатурою і складами значень трохи)

Проблема швидкодії при використанні позиції документа замість дати в віртуальних таблицях

Є додатковий індекс по вимірюванню Склад.

Проблема швидкодії при використанні позиції документа замість дати в віртуальних таблицях

Виконуємо запит з різним значенням параметра "період":

Проблема швидкодії при використанні позиції документа замість дати в віртуальних таблицях

Виконуємо ці запити кілька разів і отримуємо такі результати:

Заміри зроблені для 3х різних значень "Max Degree of Parallelism" сервера MSSQL.

Є різні думки з приводу параметра MAXDOP. 1С-ники частіше схиляються до встановлення одиниці. А ось, наприклад, думка DBA, які адмініструють інші види додатків :).
Але питання в іншому.

У всіх 4х випадках платформа генерує приблизно однакові запити з двома частинами:

Кінцевий залишок виходить різницею цих двох таблиць.

З вибіркою підсумків в частині швидкодії все добре - в таблиці є кластерний індекс з усіма вимірами, для якого умови запиту добре підходять.

А ось з вибіркою з таблиці рухів явно є проблема.

Для умови з позицією документа запит має вигляд:

Для умови з датою запит має вигляд:

Явно в першому випадку запит більш складний для сприйняття оптимізатором.

Винесемо обидва підзапиту в SQL Server management Studio і подивимося як вони виконуються:

Статистика введення / виведення і тривалість виконання:

Проблема швидкодії при використанні позиції документа замість дати в віртуальних таблицях

Перший запит (з позицій по документу) виконався в 4,5 рази довше другого і зажадав у 8 разів більше логічних читань.

Проблема швидкодії при використанні позиції документа замість дати в віртуальних таблицях

Структура ідентична, але використовувані параметри різні.
Для першого запиту Seek Predicate вказано тільки один (період менше 1 травня), а для другого - обидва обмеження по періоду.

Варіант вирішення проблеми:

Якщо проблема у вас підтверджується, то бажано по максимуму відмовитися від використання Межі і МоментаВремені при відборі по періоду в запитах до віртуальних таблиць. Якщо подібний запит є в процедурі проведення документа, то відбір залишків по позиції документа потрібен не завжди, а тільки тоді, коли документ НЕ є першим в секунді і документи впливають один на одного. Залежно від інтенсивності документообігу, це може істотно знизити кількість запитів з небажаними параметрами.

Наприклад, під час запису документа контролювати - чи є записи в регістрі в даній секунді раніше поточного документа за таким же Складу. Якщо немає, то відбирати залишки за датою, якщо так - по позиції документа:

При цьому варіант спрощення запиту з позицією документа, який дозволить усунути цю проблему, існує. На жаль, зробити це можуть тільки розробники платформи.
Я описав цю ситуацію і варіант оптимізації в партнерській конференції.
У кого є доступ - буду вдячний за "+1" в тій темі.

Схожі статті