Зріз останніх на кожну дату в скд і в запиті

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

Перший набір даних:

Як приклад, створимо звіт по продажах, в якому окремим колонкою будемо виводити ціну з прайсу на дату продажу.

Створимо набір даних-запит «ПродажіОбороти»:

Зріз останніх на кожну дату в скд і в запиті

Зараз наш звіт буде мати наступний вигляд:

Зріз останніх на кожну дату в скд і в запиті

Тепер необхідно додати до звіту колонку «Ціна по прайсу», яка буде підтягуватися з регістра відомостей «Ціни номенклатури» на дату продажу.

Другий набір даних:

Додамо другий набір даних-запит «Ціни», ціни будемо брати для фіксованого типу цін:

В даному наборі даних три параметра: Дата, Номенклатура і тип цін. З низ найцікавіші Дата і Номенклатура. Вони будуть використані при з'єднанні наборів даних, причому параметр даних присутній як в параметрах віртуальної таблиці, так і в обраних полях.

З'єднання наборів:

Приступимо до основної «фішку» даного методу - з'єднанням наборів:

Зріз останніх на кожну дату в скд і в запиті

Тут найголовніше правильно налаштувати параметри. Якщо вказано параметр, то СКД передає в приймач зв'язку параметри, зазначені в з'єднанні. Значеннями цих параметрів будуть значення відповідних полів джерела зв'язку.

Далі додамо поле ціна в ресурси і в обрані поля.

Зріз останніх на кожну дату в скд і в запиті

Зріз останніх на кожну дату в скд і в запиті

результат:

Тепер можна формувати звіт. Перевіримо правильність роботи звіту на прикладі «Дивану для відпочинку».

Зріз останніх на кожну дату в скд і в запиті

У запиті:

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

Даний пакетний запит містить три підзапиту. Розглянемо їх докладніше.

Перший запит пакету групує дані за періодом, контрагенту і номенклатурі і поміщає їх в тимчасову таблицю втБезЦени. Далі ми будемо з'єднувати цю таблицю з таблицею цін номенклатури і отримаємо невеликий виграш в тому, що з'єднувати будемо вже згруповані дані.

У другому запиті пакета ми з'єднуємо тимчасову таблицю з регістром відомостей «ЦениНоменклатури» при цьому з регістра відомостей ми вибираємо МАКСИМАЛЬНУ дату з менших або рівних дат. Результат цього запиту також поміщаємо в тимчасову таблицю (втМаксПеріод). Подивимося, які дані потрапляють в цю таблицю:

Зріз останніх на кожну дату в скд і в запиті

В останньому запиті пакета, ми ще раз з'єднуємо тимчасову таблицю з таблицею цін номенклатури. На цей ми з'єднуємо таблиці по номенклатурі і періоду.

Підсумковий результат запиту:

Зріз останніх на кожну дату в скд і в запиті

Як ми бачимо результати виведення цін в обох випадках (через СКД і через запит) виявилися однакові.

22. Ігор (I_G_O_R) 45 14.11.10 14:42 Зараз в темі

1) це запит зі статті з виправленням помилок і без індексів (без індексів показав кращі результати):

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

Bold Enough; SamMix; vasyak319; WellMaster; serge_focus; Zircool; SirYozha; + 7 - Відповісти

23. Ігор Ісхаков (Ish_2) 986 14.11.10 16:39 Зараз в темі

(22) Знав, що ти відповіси.
Задав ти завдання.
Так що ж краще "в середньому" для нормальної роботи в УТ.

Дуже схоже. що при відпрацюванні твого запиту під час першого запуску sql-сервер створює і вантажить в пам'ять ВЕСЬ індекс регістра по полю Період. Саме робота за цим індексом з'їдає 90% часу. При наступних запусках цього не відбувається тому і час всього 10 сек.
АЛЕ.
Якщо після першого запуску відбулися серйозні зміни в регістрі цін (користувачі почали роботу), то старий індекс в кеші не може бути використаний і він повинен бути перестворює. І тоді при наступному запуску твого звіту - знову гальма.
Свою першу статтю пам'ятаєш. З тих пір прогнозую з побоюванням.
Так що = це всього лише припущення.
Якщо з ними усе гаразд. то тоді я б віддав перевагу запитом наведеному в статті (з усіма необхідними виправленнями і доповненнями)

25. Ігор (I_G_O_R) 45 14.11.10 18:17 Зараз в темі

(23) а як дізнатися точно що скл робив весь цей час, план виконання я дивився і він не змінюється
(24) а щодо індексів: з індексами десь рази в два повільніше виконувався запит

26. Ігор Ісхаков (Ish_2) 986 14.11.10 18:28 Зараз в темі

(25) Прав я чи ні - можна дізнатися якщо на гарячому сервері після першого запуску твого звіту в регістр Ціни занести 1000 нових записів. І після цього запустити твій звіт.
Якщо час буде 400 сек - то я прав. Якщо 10 сек - то я не маю рації.

27. Ігор (I_G_O_R) 45 14.11.10 22:03 Зараз в темі

(26) та мав рацію але на 50%)), заніс 10000 записів в один день і час запиту склало 175 сек, а потім знову 10. Потім я переписав на тимчасові таблиці свій запит і додав в запит з топіка зріз останніх, в результаті на холодному сервері час виконання обох запитів 45-50 сек, на гарячому 35-40. Не розумію тільки чому раніше були більш стабільні результати. Багато тестів не робив, тому мій запит виграє, то з топіка, взагалі буду вважати що однаково. В останніх запитах тепер мені не подобається, що в регістрі Ціни номенклатури купа індексів (в моїй базі тільки по ЦениНоменклатури дані - 236 Мб, а індекси 730 Мб), які майже ніяк не використовуються

28. Ігор Ісхаков (Ish_2) 986 14.11.10 22:31 Зараз в темі

(27) Збив з пантелику. Зовсім.
Збентежив цими 50% (175 сек). малозрозумілі поки і (45-50), (35-40).