Последний раз про срез последних (на каждую дату в запросе)

Публикация № 1302246 15.02.21

Приемы и методы разработки - Запросы

срез замер производительность запрос эксперимент

Срез последних на каждую дату в запросе. Известные факты о задаче: часто встречается на испытаниях соискателей на работу программистом 1с, постоянно провоцирует споры об оптимальном решении. В данном тексте приводятся замеры производительности различных вариантов решения задачи.

На проведение данного исследования меня натолкнула статья «Срез на даты за период. Шаблон запроса» с комментариями. Суть статьи: автор привел два варианта решения известной задачи — традиционный и свой собственный («интервальный»). В комментариях оба варианта подверглись резкой критике за сложность — большой объем текста, временные таблицы. Цитирую критиков:

«давно уже подобную задачу решают одним запросом (без всяких временных таблиц) с двумя левыми соединениями»

«Не вникал в смысл задачи, но срез на дату чего-либо по периоду делается простым 1 запросом без всяких ВТ.»

Комментаторы оказались людьми слова и дела, предложили два своих варианта, без временных таблиц, в один запрос.

Изначально, я был сторонником традиционного способа — он давно известен, интуитивно понятен (но это не точно) и более-менее оптимальный по производительности (это тоже не точно). Вариант автора — тоже интересный, мне такая идея в голову не приходила, но, почему-то, он мне показался менее производительным.

Оба варианта из комментариев — короткие, лаконичные, но затратные по ресурсам, на мой взгляд.

Но вообще, интересно провести исследование, и цифрами показать, какой из вариантов лучше и на сколько.

Почти год я собирался с мыслями. Потом провел эксперимент. Еще почти год созревал изложить это в виде статьи. Наконец, созрел :)

По ходу изучения темы, мне попался еще один вариант в статье «Минимализмы» п.4. Тоже в один запрос, довольно диковинное решение, вряд ли применимое на практике, но интересное.

Итого получилось 5 вариантов.

На мой взгляд, все такие задачи в реальности примерно одного типа. Возьмем самую типичную:

  • организация продает товары (документ Реализация товаров);
  • их цена хранится в регистре (периодический регистр сведений Цены) и меняется во времени;
  • продавец может устанавливать скидку в момент продажи, но не более некоторого процентного значения;
  • в какой-то момент времени нужно проверить, что все скидки действительно не превышали этого порога;
  • если превышали, то где, когда, на сколько;
  • значения скидок в документах не хранятся (или хранятся, но мы им не доверяем), а считаем отношение цены из документа продажи к значению цены их регистра на дату.
 
Что ж, осталось собрать тестовый стенд и запустить наши запросы:

Железо (ноутбук):

  • процессор AMD Ryzen 5 2500U,
  • оперативная память 12 Gb,
  • диск SSD Samsung PM871b SATA3

Программное обеспечение:

  • Windows 10 Home (64)
  • Microsoft SQL Server 2017 14.0.2002.14 (X64) Developer Edition (64-bit) (для наглядности, я отключил параллельное использование ядер процессора: Max degree of parallelism = 1)
  • 1С:Предприятие 8.3 (8.3.15.1700) (64)

Создаем простую каркасную конфигурацию: «Номенклатура», «Контрагенты», «Продажа товаров», «Цены».

Конфигурация с обработкой инициализации опубликована здесь: github.com/boroda310/slice-slice-slice. В папке configuration — файлы конфигурации.

Инициализируем случайными данными.

1000 товаров:

 
Инициализация 1

Цены на начало периода, случайные переоценки в периоде:

 
Инициализация 2

Продажи в периоде:

 
Инициализация 3

Порог скидки для отбора данных принимаем равным 10, Чтобы не тратить время на вывод результатов, отобранные данные помещаем во временную таблицу и выводим только количество получившихся строк.

Файл для консоли запросов с текстами запросов опубликован здесь: github.com/boroda310/slice-slice-slice в папке requestconsole.

 
Запрос Вариант А (традиционный)
 
Запрос Вариант Б (интервальный)
 
Запрос Вариант В (в один запрос, без группировки)
 
Запрос Вариант Г (в один запрос, с группировкой)
 
Запрос Вариант Д («эшелонный» из ст. «Минимализмы»)

Я запускал все эти запросы за два периода — первый квартал 2020 г. и первое полугодие 2020 г. — на эти периоды генерировались случайные документы и цены. Замерял время выполнения. В ходе анализа планов запросов определился еще один важный показатель — количество обрабатываемых строк. Другие показатели оказались неинформативными.

Вот пример планов запроса для варианта А и варианта В, как наилучшего из однозапросных:

Вот такие результаты у меня получились:

Вариант

Время выполнения, с.

Обработано строк

  3 мес. 6 мес. 3 мес. 6 мес.
А (традиционный) 4.9 10.2 1 626 647 3 195 284
Б (интервальный) 4.3 10.3 1 626 647 3 195 284
В (без группировки) 10.0 26.2 2 107 110 13 596 463
Г (с группировкой) 20.1 105.0 4 387 711 27 379 466
Д (эшелонный) 20.8 71.6 4 897 463 15 876 311

 

Варианты А и Б лидируют и не сильно отличаются друг от друга. Результат остальных довольно безрадостен.

Можно заключить: срез последних в один запрос реализовать можно. Но лучше — не надо.

Репозиторий тестовой конфигурации: github.com/boroda310/slice-slice-slice

Отсылки:

Специальные предложения

Вознаграждение за ответ
Показать полностью
Лучшие комментарии
25. ildarovich 7562 17.02.21 21:42 Сейчас в теме +10 $m
(24) Нет, не так.

Выводы, возможно, справедливы не для мультисреза последних вообще, а для запроса, решающего задачу поиска слишком больших скидок в документах продажи. И то, при еще нескольких сделанных оговорках.

Кстати, а индексирование по измерению "Номенклатура" в регистре сведений "ЦеныНоменклатуры" когда и зачем было отключено? Ну или почему оно "ведущим" не было сделано? Я имею ввиду тестовую конфигурацию.

Хотелось еще, чтобы вы вот такие варианты запроса (В) на вашем стенде попробовали (включив индексацию, разумеется). Такой:
ВЫБРАТЬ
	ПродажаТовара.Ссылка КАК Ссылка,
	ПродажаТовараТовары.Номенклатура КАК Номенклатура,
	ПродажаТовара.Контрагент КАК Контрагент,
	ПродажаТовараТовары.Количество КАК Количество,
	100 * (ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) / ЦеныНоменклатуры.Цена КАК Скидка
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
	Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТовара КАК ПродажаТовара
		ПО (ПродажаТовараТовары.Ссылка = ПродажаТовара.Ссылка)
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры.Номенклатура)
			И (ПродажаТовараТовары.Цена < 0.9 * ЦеныНоменклатуры.Цена) 
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры.Период)
			И 1 НЕ В 
			(ВЫБРАТЬ 1 ИЗ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры2 
			ГДЕ (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры2.Номенклатура)
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры2.Период)
			И (ЦеныНоменклатуры2.Период > ЦеныНоменклатуры.Период))
ГДЕ
	ПродажаТовара.Дата МЕЖДУ &НачалоПериода И &КонецПериода
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(*) КАК Поле1
ИЗ
	ВременнаяТаблица КАК ВременнаяТаблица
Показать

А также такой:
ВЫБРАТЬ
	ПродажаТовара.Ссылка КАК Ссылка,
	ПродажаТовараТовары.Номенклатура КАК Номенклатура,
	ПродажаТовара.Контрагент КАК Контрагент,
	ПродажаТовараТовары.Количество КАК Количество,
	100 * (ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) / ЦеныНоменклатуры.Цена КАК Скидка
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
	Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТовара КАК ПродажаТовара
		ПО (ПродажаТовараТовары.Ссылка = ПродажаТовара.Ссылка)
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры.Номенклатура)
			И (ПродажаТовараТовары.Цена < 0.9 * ЦеныНоменклатуры.Цена) 
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры.Период)
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры2
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры2.Номенклатура)
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры2.Период)
			И (ЦеныНоменклатуры2.Период > ЦеныНоменклатуры.Период)
ГДЕ
	ПродажаТовара.Дата МЕЖДУ &НачалоПериода И &КонецПериода
	И ЦеныНоменклатуры2.Период ЕСТЬ NULL
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(*) КАК Поле1
ИЗ
	ВременнаяТаблица КАК ВременнаяТаблица
Показать

А мой запрос лучше применить вот в таком варианте:
ВЫБРАТЬ
	ПродажаТовара.Ссылка КАК Ссылка,
	ПродажаТовараТовары.Цена КАК ЦенаДокумента,
	МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ) * &Много + 0.9 * ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) - МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ)) * &Много КАК Оверскидка,
	ПродажаТовара.Контрагент КАК Контрагент,
	ПродажаТовараТовары.Номенклатура КАК Номенклатура,
	ПродажаТовараТовары.Количество КАК Количество,
	ПродажаТовараТовары.НомерСтроки КАК НомерСтроки
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
	Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТовара КАК ПродажаТовара
		ПО (ПродажаТовараТовары.Ссылка = ПродажаТовара.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры.Номенклатура)
			И (ЦеныНоменклатуры.Период <= ПродажаТовара.Дата)
ГДЕ
	ПродажаТовара.Дата МЕЖДУ &НачалоПериода И &КонецПериода

СГРУППИРОВАТЬ ПО
	ПродажаТовара.Ссылка,
	ПродажаТовараТовары.Номенклатура,
	ПродажаТовараТовары.Цена,
	ПродажаТовара.Контрагент,
	ПродажаТовараТовары.Количество,
	ПродажаТовараТовары.НомерСтроки

ИМЕЮЩИЕ
	МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ) * &Много + 0.9 * ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) < МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ)) * &Много
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(*) КАК Поле1
ИЗ
	ВременнаяТаблица КАК ВременнаяТаблица
Показать
Ну и еще установок цен, чтобы было ближе к реальности, нужно побольше. Например, не 24, а 124. Их можно на 2,5 года растянуть. Начав с 01.01.2019, например. Это я к тому, что 9 записей в РС на номенклатуру - это вообще ни о чем. Нечего оптимизировать, никакие хитрые приемы не нужны и конкурса именно по срезу последних не получается.
RibD; user1067792; Simonov_NPM; Serg O.; +4 1 Ответить
Остальные комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. kozusenok 45 15.02.21 13:09 Сейчас в теме
А мне ещё вот такой вариант приглянулся где-то тут на форуме
ВЫБРАТЬ
	ЦеныНоменклатуры.Период КАК Период,
	ЦеныНоменклатуры.Номенклатура КАК Номенклатура,
	ЦеныНоменклатуры.Цена КАК Цена
ПОМЕСТИТЬ ВсеЦеныНоменклатуры
ИЗ
	РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
ГДЕ
	ЦеныНоменклатуры.Период <= &КонецПериода
;

ВЫБРАТЬ
	Продажи.Регистратор КАК Документ,
	Продажи.Контрагент КАК Контрагент,
	Продажи.Номенклатура КАК Номенклатура,
	Продажи.Количество КАК Количество,
	ВсеЦеныНоменклатуры.Цена КАК Цена
ИЗ
	РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, Авто, ) КАК Продажи
	ЛЕВОЕ СОЕДИНЕНИЕ ВсеЦеныНоменклатуры КАК ВсеЦеныНоменклатуры
	ПО Продажи.Номенклатура = ВсеЦеныНоменклатуры.Номенклатура
		И ВсеЦеныНоменклатуры.Период В
			(ВЫБРАТЬ
				МАКСИМУМ(ЦеныНоменклатуры.Период)
			ИЗ
				ВсеЦеныНоменклатуры КАК ЦеныНоменклатуры
			ГДЕ
				ЦеныНоменклатуры.Период <= Продажи.ПериодСекунда
				И ЦеныНоменклатуры.Номенклатура = Продажи.Номенклатура)
Показать
ildarovich; +1 Ответить
2. randomus 235 15.02.21 15:28 Сейчас в теме
(1) надеюсь, это сарказм ;)
3. randomus 235 15.02.21 18:33 Сейчас в теме
(2) я не поленился и замерял этот вариант. За первый квартал время выполнения 23 сек.
это очень плохой вариант. План запроса:
Прикрепленные файлы:
t278; MGraf; shard; BigB; +4 Ответить
14. buganov 191 17.02.21 07:33 Сейчас в теме
(1) без обид, но запрос ужасный. Начиная от неограниченного количества кортежей снизу во временной таблице, заканчивая чтением регистра накопления как попало.
randomus; +1 Ответить
34. director04 3636 18.02.21 10:53 Сейчас в теме
(1) Использовать в соединении таблиц запрос - это губить производительность системы.
На малых объемах данных можно. На больших - повесите систему....
40. ildarovich 7562 19.02.21 10:05 Сейчас в теме
(34) Тем не менее, посмотрите результаты в (28). Объемы данных там не маленькие. Производительность не то, чтобы не погублена, а даже многократно спасена.
45. triviumfan 30 24.02.21 09:15 Сейчас в теме
(40) Опа, с возвращением! Сергей, можно ли от вас ждать новых статей? Совсем пропали.
4. RustIG 16.02.21 17:04 Сейчас в теме
Почти год я собирался с мыслями. Потом провел эксперимент. Еще почти год созревал изложить это в виде статьи. Наконец, созрел :)

Коллеги, цените публикации!
у меня лично также - уходит много времени "чтобы собраться", "чтобы написать". реально, это труд.
Dunda; KEV8383; ardn; Drivingblind; randomus; biimmap; +6 Ответить
5. RustIG 16.02.21 17:07 Сейчас в теме
(0) План запроса какой обработкой выводили? Что за зверь такой?
8. randomus 235 16.02.21 18:18 Сейчас в теме
(5) Стандартная консоль запросов с ИТС, галочка показать план запроса. Если что, в конфигурацию встроена. Не так красиво, как в профайлере, но для данного случая показателей достаточно
Serg O.; RustIG; +2 Ответить
6. RustIG 16.02.21 17:18 Сейчас в теме
(0) Коллеги, не кидайте камнями. Но я пару-тройку подобных задач решал по другому.
Создал регистр сведений (иногда их несколько было, иногда одного достаточно - зависит от показателей отчета , который требуется Заказчику) - при проведении Реализации сохраняю в регистр сведений цены на каждый товар из реализации, скидку, цены на товар из общего регистра ЦеныНоменклатуры, ответственного.
Далее Отчет строю по этому регистру. Информация копится быстро, согласен, что сведения дублируются из других регистров -но такова суть управленческого учета - много регистров сведений и накоплений почти дублируют друг друг, отличаясь только одним-двумя измерениями.
Подобная схема реализации очень быстро внедряется, легко адаптируется при изменении ТЗ Заказчика.
Через год -два делаю свертку.

Плюс подобная задача возникает при расчете итоговых остатков на расчетных счетах на каждый день - для финансового учета и планирования. Подвести итоги пока не могу, процесс автоматизации финучета "для себя" временно приостановлен.
randomus; jONES1979; +2 Ответить
9. randomus 235 16.02.21 18:22 Сейчас в теме
(6) Конечно, если есть возможность хранить промежуточные результаты, то почему бы нет. Я просто протестил известные варианты известной вычислительной задачи.
16. Yashazz 4345 17.02.21 08:55 Сейчас в теме
(6) Разумеется, в общем случае архитектурное решение гораздо лучше, его заточить под конкретику можно. Но объём растёт. Равно как и поиграть с таблицами значений, пока они не убивают сеансовый кэш, иногда проще и в разы быстрее. Извечный поиск баланса между местом на диске, местом в кэше/оперативке и скоростью исполнения.
36. mixsture 18.02.21 11:17 Сейчас в теме
(6)
стр сведений (иногда их несколько было, иногда одного достаточно - зависит от показателей отчета , который требуется Заказчику) - при проведении Реализации сохраняю в регистр сведений цены на каждый товар из реализации, скидк


и я тоже за такое решение. Просто надо раз и навсегда признаться, что типовые сущности не позволяют выполнить такой запрос эффективно. Поэтому и следует использовать заранее подготовленные данные - этот подход очень распространен в конфигурациях, хорошо разделяет сложность задачи, убирая его с отчета, и хорошо модифицируется и поддерживается в дальнейшем.
Это, несомненно, сдвигает баланс системы с OLTP -> OLAP, что выливается в более долгое проведение доков при более быстром формировании отчетов.
randomus; RustIG; +2 Ответить
7. RustIG 16.02.21 17:25 Сейчас в теме
(0) кому-то большие запросы - это неизбежность, с которой приходится мириться.... я стараюсь обходить большие запросы в прямом смысле слова - часто получаю ТаблицуЗначений из Запроса вместо Выборки. Далее в ТаблицеЗначений меняю сведения или обрабатываю строки, и далее окончательный результат возвращаю.
Опять-таки, не считаю что это единственно правильный метод, но архитектура красивого решения в этом и заключается, что мы используем баланс: минимум соединений таблиц в запросах - минимум физических таблиц для хранения информации.
Что-то подобное я пробовал описать в публикации, но при повторном прочтении, понимаю сам, что написал сложным языком. Поэтому соррян заранее: https://infostart.ru/1c/articles/195627/
mashinist; Yashazz; randomus; jONES1979; +4 Ответить
11. randomus 235 16.02.21 18:35 Сейчас в теме
(7) В таблицу значений - нормальное решение, тоже часто использую. С другой стороны, соединения - это основное назначение SQL-сервера. Он на них натаскан и оптимизирован :) Поэтому я наоборот стараюсь максимальное количество соединений отдать на выполнение SQL-серверу. Естественно, их надо грамотно строить и не использовать сложных условий в связях. Если не получается упростить условия, тогда лучше без них.
Со статьей ознакомлюсь, спасибо.
10. RustIG 16.02.21 18:33 Сейчас в теме
(8) спасибо за статью и ответ. ловите вознаграждение.
randomus; +1 Ответить
12. randomus 235 16.02.21 18:47 Сейчас в теме
(10) спасибо! Мне пришла идея, как распорядится вознаграждением :) Я добавил еще 9 sm.
И все 10 получит тот, кто пришлет свой вариант решения, если он будет в один запрос и быстрее варианта В. Либо быстрее варианта А без ограничения количества запросов, подзапросов, временных таблиц
13. ilya2184 62 16.02.21 23:52 Сейчас в теме
Не пробовал индексировать поля соединения, например в традиционном варианте? Может получиться быстрее (а может и медленнее)
15. Yashazz 4345 17.02.21 08:51 Сейчас в теме
А кто-нибудь замерял, что в общем случае быстрее -
ПродажаТовара.Дата >= вт_ПериодыЦен.НачалоПериода И ПродажаТовара.Дата < вт_ПериодыЦен.КонецПериода
или
ПродажаТовара.Дата МЕЖДУ вт_ПериодыЦен.НачалоПериода И ДОБАВИТЬКДАТЕ(вт_ПериодыЦен.КонецПериода, СЕКУНДА, -1)

кто знает?
19. randomus 235 17.02.21 12:47 Сейчас в теме
(15) думаю, что примерно одинаково. позже проверю
20. randomus 235 17.02.21 15:28 Сейчас в теме
(15) проверил :) оценки в плане запроса одинаковые, но время выполнения у первого варианта немного меньше
22. Yashazz 4345 17.02.21 17:59 Сейчас в теме
(20) Спасибо. Вообще, Вам спасибо, дельная хорошая публикация.
17. Simonov_NPM 17.02.21 10:11 Сейчас в теме
Традиционный запрос
ВЫБРАТЬ РАЗЛИЧНЫЕ
	ПродажиОбороты.Период КАК Дата
ПОМЕСТИТЬ вт_ДатыПродаж
ИЗ
	РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК ПродажиОбороты
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ЦеныНоменклатуры.Период,
	ЦеныНоменклатуры.Номенклатура,
	ЦеныНоменклатуры.Цена
ПОМЕСТИТЬ ВТ_Цены
ИЗ
	РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
ГДЕ
	ЦеныНоменклатуры.ТипЦен = &ТипЦен
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	МАКСИМУМ(ВТ_Цены.Период) КАК Период,
	ВТ_Цены.Номенклатура КАК Номенклатура,
	вт_ДатыПродаж.Дата КАК Дата
ПОМЕСТИТЬ вт_ДатыАктуальныхЦен
ИЗ
	вт_ДатыПродаж КАК вт_ДатыПродаж
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Цены КАК ВТ_Цены
		ПО ВТ_Цены.Период <= вт_ДатыПродаж.Дата

СГРУППИРОВАТЬ ПО
	вт_ДатыПродаж.Дата,
	ВТ_Цены.Номенклатура
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ПродажиОбороты.Период КАК Период,
	ПродажиОбороты.Контрагент КАК Контрагент,
	ПродажиОбороты.Номенклатура КАК Номенклатура,
	ПродажиОбороты.КоличествоОборот КАК Количество,
	ПродажиОбороты.СтоимостьОборот,
	ВТ_Цены.Цена
ИЗ
	РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК ПродажиОбороты
		ЛЕВОЕ СОЕДИНЕНИЕ вт_ДатыАктуальныхЦен КАК вт_ДатыАктуальныхЦен
		ПО ПродажиОбороты.Номенклатура = вт_ДатыАктуальныхЦен.Номенклатура
			И ПродажиОбороты.Период = вт_ДатыАктуальныхЦен.Дата
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Цены КАК ВТ_Цены
		ПО ПродажиОбороты.Номенклатура = ВТ_Цены.Номенклатура
			И (вт_ДатыАктуальныхЦен.Период = ВТ_Цены.Период)
Показать

показал время 287 на 6600 записях

Плохой запрос
ВЫБРАТЬ
	Продажи.Период КАК Период,
	Продажи.Контрагент КАК Контрагент,
	Продажи.Номенклатура КАК Номенклатура,
	Продажи.КоличествоОборот КАК Количество,
	Продажи.СтоимостьОборот КАК Стоимость,
	ЦеныНоменклатуры.Цена
ИЗ
	РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК Продажи
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО Продажи.Номенклатура = ЦеныНоменклатуры.Номенклатура
			И (ЦеныНоменклатуры.ТипЦен = &ТипЦен)
			И (ЦеныНоменклатуры.Период В
				(ВЫБРАТЬ
					МАКСИМУМ(Цены.Период)
				ИЗ
					РегистрСведений.ЦеныНоменклатуры КАК Цены
				ГДЕ
					Цены.Период <= Продажи.Период
					И Цены.Номенклатура = Продажи.Номенклатура
					И Цены.ТипЦен = &ТипЦен))  
Показать



показал время 84 на 6600 записях

в отличии от плохого запроса из первого комментария, в подзапросе условия соединения используется реальная таблица (РегистрСведений.ЦеныНоменклатуры) вместо временной

База УПП, Субд sql2012

Показатель i/o конечно значительно выше у плохого запроса.
Eeeehhhh; zqzq; +2 Ответить
46. triviumfan 30 24.02.21 09:21 Сейчас в теме
47. Simonov_NPM 24.02.21 10:00 Сейчас в теме
(46) Для того чтобы два раза не обращаться к физической таблице
18. BackinSoda 17.02.21 11:49 Сейчас в теме
А я думал, что "интервальный" является "традиционным".
Спасибо за статью !
21. ildarovich 7562 17.02.21 16:45 Сейчас в теме
Если разобраться: от чего зависит сравнительное время выполнения этих запросов, то результаты при заданных условиях окажутся очевидными без всякого вычислительного эксперимента. Кстати, коррелированный запрос (1), по-моему мнению, зря сбросили со счетов. По условиям эксперимента у вас одна номенклатура продается в среднем 18 раз за день, а меняет свою цену - раз в двадцать дней, то есть - 4,5 раза за квартал. Соединение самих с собой 4,5 записей с 4,5 записями (упрощаю, так как есть нелинейность) - это условия, в которых проблема тэта соединений вообще не заметна. То есть считать заново 18 раз в день то, что меняется раз в 20 дней просто глупо. Поэтому однозапросный метод, в котором на каждую дату все заново считается, здесь не подходит не про причине своей ущербности, а по причине избыточного повторения вычислений.

Мой запрос из "минимализмов" будет работать примерно на уровне других методов (а какие-то и опредит), когда продаж одной номенклатуры будет не больше одной в день, а ее переоценок хотя бы сотня (тысяча вообще хорошо). Понятно, что в жизни это бывает редко, но ведь кроме переоценок - продаж есть и другие сценарии.

Так что ваши выводы справедливы не в общем, а частном случае соотношения числа записей в периодическом регистре и количества требуемых дат в множественном срезе последних, ИМХО.

Ну и, пользуясь случаем, прорекламирую тут свой метод индексирования интервалов для борьбы с фамильной болезнью периодических регистров сведений - деградацией производительности при росте количества записей.
zqzq; RustIG; +2 Ответить
23. Yashazz 4345 17.02.21 18:01 Сейчас в теме
(21) Вот да, от бизнес-смысла каждой конкретной задачи плясать надо, и выбирать решение именно исходя из ситуации.
24. randomus 235 17.02.21 21:11 Сейчас в теме
(21) В реальной жизни условная "переоценка" всегда реже условной "продажи".
Хотелось бы увидеть хоть один реальный обратный пример. Соответственно, мои выводы справедливы - в реальной жизни :)
25. ildarovich 7562 17.02.21 21:42 Сейчас в теме +10 $m
(24) Нет, не так.

Выводы, возможно, справедливы не для мультисреза последних вообще, а для запроса, решающего задачу поиска слишком больших скидок в документах продажи. И то, при еще нескольких сделанных оговорках.

Кстати, а индексирование по измерению "Номенклатура" в регистре сведений "ЦеныНоменклатуры" когда и зачем было отключено? Ну или почему оно "ведущим" не было сделано? Я имею ввиду тестовую конфигурацию.

Хотелось еще, чтобы вы вот такие варианты запроса (В) на вашем стенде попробовали (включив индексацию, разумеется). Такой:
ВЫБРАТЬ
	ПродажаТовара.Ссылка КАК Ссылка,
	ПродажаТовараТовары.Номенклатура КАК Номенклатура,
	ПродажаТовара.Контрагент КАК Контрагент,
	ПродажаТовараТовары.Количество КАК Количество,
	100 * (ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) / ЦеныНоменклатуры.Цена КАК Скидка
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
	Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТовара КАК ПродажаТовара
		ПО (ПродажаТовараТовары.Ссылка = ПродажаТовара.Ссылка)
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры.Номенклатура)
			И (ПродажаТовараТовары.Цена < 0.9 * ЦеныНоменклатуры.Цена) 
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры.Период)
			И 1 НЕ В 
			(ВЫБРАТЬ 1 ИЗ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры2 
			ГДЕ (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры2.Номенклатура)
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры2.Период)
			И (ЦеныНоменклатуры2.Период > ЦеныНоменклатуры.Период))
ГДЕ
	ПродажаТовара.Дата МЕЖДУ &НачалоПериода И &КонецПериода
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(*) КАК Поле1
ИЗ
	ВременнаяТаблица КАК ВременнаяТаблица
Показать

А также такой:
ВЫБРАТЬ
	ПродажаТовара.Ссылка КАК Ссылка,
	ПродажаТовараТовары.Номенклатура КАК Номенклатура,
	ПродажаТовара.Контрагент КАК Контрагент,
	ПродажаТовараТовары.Количество КАК Количество,
	100 * (ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) / ЦеныНоменклатуры.Цена КАК Скидка
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
	Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТовара КАК ПродажаТовара
		ПО (ПродажаТовараТовары.Ссылка = ПродажаТовара.Ссылка)
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры.Номенклатура)
			И (ПродажаТовараТовары.Цена < 0.9 * ЦеныНоменклатуры.Цена) 
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры.Период)
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры2
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры2.Номенклатура)
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры2.Период)
			И (ЦеныНоменклатуры2.Период > ЦеныНоменклатуры.Период)
ГДЕ
	ПродажаТовара.Дата МЕЖДУ &НачалоПериода И &КонецПериода
	И ЦеныНоменклатуры2.Период ЕСТЬ NULL
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(*) КАК Поле1
ИЗ
	ВременнаяТаблица КАК ВременнаяТаблица
Показать

А мой запрос лучше применить вот в таком варианте:
ВЫБРАТЬ
	ПродажаТовара.Ссылка КАК Ссылка,
	ПродажаТовараТовары.Цена КАК ЦенаДокумента,
	МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ) * &Много + 0.9 * ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) - МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ)) * &Много КАК Оверскидка,
	ПродажаТовара.Контрагент КАК Контрагент,
	ПродажаТовараТовары.Номенклатура КАК Номенклатура,
	ПродажаТовараТовары.Количество КАК Количество,
	ПродажаТовараТовары.НомерСтроки КАК НомерСтроки
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
	Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТовара КАК ПродажаТовара
		ПО (ПродажаТовараТовары.Ссылка = ПродажаТовара.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры.Номенклатура)
			И (ЦеныНоменклатуры.Период <= ПродажаТовара.Дата)
ГДЕ
	ПродажаТовара.Дата МЕЖДУ &НачалоПериода И &КонецПериода

СГРУППИРОВАТЬ ПО
	ПродажаТовара.Ссылка,
	ПродажаТовараТовары.Номенклатура,
	ПродажаТовараТовары.Цена,
	ПродажаТовара.Контрагент,
	ПродажаТовараТовары.Количество,
	ПродажаТовараТовары.НомерСтроки

ИМЕЮЩИЕ
	МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ) * &Много + 0.9 * ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) < МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ)) * &Много
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(*) КАК Поле1
ИЗ
	ВременнаяТаблица КАК ВременнаяТаблица
Показать
Ну и еще установок цен, чтобы было ближе к реальности, нужно побольше. Например, не 24, а 124. Их можно на 2,5 года растянуть. Начав с 01.01.2019, например. Это я к тому, что 9 записей в РС на номенклатуру - это вообще ни о чем. Нечего оптимизировать, никакие хитрые приемы не нужны и конкурса именно по срезу последних не получается.
RibD; user1067792; Simonov_NPM; Serg O.; +4 1 Ответить
28. Serg O. 202 18.02.21 09:38 Сейчас в теме
согласен, товаров и установок цен должно быть больше

сравнил запрос А и Ваши запрос на "реальной" торговой базе за 1 месяц (январь 2021)
установки цен идут ежедневно по несколько 4-10 тыс. товаров (133 тыс. записей рс.ЦеныНоменклатурын за месяц )
результат запроса: 18 359

"лучший" запрос А - выполнялся: 65 - 66 сек,
Ваш 1 запрос: 2 сек !!!
Ваш 2 запрос: 15 сек
Ваш 3 запрос: 1,25 - 1,32 сек (при Много = 31 день) - наилучший результат!
ildarovich; +1 Ответить
32. randomus 235 18.02.21 10:01 Сейчас в теме
(28) откуда я знаю как вы адаптировали "мои" запросы к реальной базе?

И что такое "много = 31 день" в "моем 3 запросе"?

Много - это в запросе Ильдаровича, и оно не в днях измеряется а в рублях.
и 31 в таком случае это не много и запрос вероятно работает не правильн.

Похоже, надо запрещать комментарии, а то холивар разгорается :)

Напишите свою статью лучше. Может я прочитаю и прояснится в голове
38. Serg O. 202 19.02.21 07:41 Сейчас в теме
(32) за Вашу статью спасибо и большой +

Данные по времени из более наполненной базы торговли я привёл для (25) ildarovich
42. randomus 235 19.02.21 12:57 Сейчас в теме
(38) Извините, неправильно понял вас. Если это результаты запросов из (25) то действительно интересно, есть над чем подумать, спасибо.
39. ildarovich 7562 19.02.21 09:42 Сейчас в теме
(28) Спасибо, очень интересно, есть о чем подумать. И, возможно, еще скорректировать выводы в (37). Получается, работа с временной таблицей (созданием и выборкой из нее) достаточно много времени на этих данных отнимает.

Единственно, &Много действительно должно быть не 31, а больше (зависит от диапазона данных). Больше диапазона изменения ресурса. Поэтому 10 000, которые в тесте - надежнее. Проверить можно, сравнив количество в результате запроса.

Хотя, если разница между 0.9 установленной цены и ценой продажи не превышают 31 рубля, результат будет тем же. А на скорости это сказываться не должно.

Интересен результат коррелированного запроса.
29. randomus 235 18.02.21 09:48 Сейчас в теме
(25)
Нет, не так.


Все таки, настаиваю на своей формулировке :) Пока не получу реальный, а не фантазийный пример, когда "срезаемая" оценка некоей сущности на 2-3 порядка превосходит количество периодов среза.

Кстати, а индексирование по измерению "Номенклатура" в регистре сведений "ЦеныНоменклатуры" когда и зачем было отключено? Ну или почему оно "ведущим" не было сделано? Я имею ввиду тестовую конфигурацию.


Я начинаю сомневаться в продуктивности дальнейшего спора.

Не было оно отключено. В регистре сведений по умолчанию создается кластерный индекс по всем измерениям по порядку следования в конфигураторе, а затем - по периоду.
Стыдно этого не знать, минус в коммент за это.

Я, кстати, пробовал индексировать поле Номенклатура отдельно - результаты немного ухудшались. Возможно, сервер тратил время на выбор нужного индекса.

Зря вы так переживаете за свой вариант, он красивый, и с этой точки зрения мне нравится больше остальных. Но это - вычислительный казус, упражнение для ума, а этот эксперимент не про хитрые приемы, а про скучную обыденность :)

Ваши варианты я попробую, сейчас тестового стенда нет под рукой. Но мне кажется - там только косметические улучшения
33. ildarovich 7562 18.02.21 10:16 Сейчас в теме
(29)
Не было оно отключено
Знаете, мне очень понравилось оформление тестовой конфигурации - было удобно и приятно с ней работать. Еще удобнее то, что я скачал ее на гитхабе, куда вы ее так любезно выложили. И вот после того как я загрузил конфигурацию из файлов, я и получил снятый флажок в ведущем измерении "Номенклатура" и отключенный по нему индекс. - Попробуйте загрузить те же файлы в чистую конфигурацию - сами это увидите.
Стыдно этого не знать
Если бы мне было стыдно от всего, чего я не знаю - давно бы сгорел от этого стыда.
Переживаю я не за свой вариант, а, как всегда, за "научную истину".
35. randomus 235 18.02.21 11:07 Сейчас в теме
(33)Всё правильно, так и было задумано. Потому что, в данном случае, достаточно индексов, которые 1с создает по умолчанию.
В гугле поиск "индексы 1с" первая ссылка.
Можно проверить средствами SQL сервера
37. ildarovich 7562 18.02.21 13:58 Сейчас в теме
(35) Вот про это я и спрашивал в (25): почему было отключено. Посмотрел по ссылке, да, все так, индекс и без этого строится.

Вообще, ничего плохого статья не советует. Я бы вообще не спорил, если бы статья называлась: Когда выгодно использовать временные таблицы на типовом примере срезов последних. Обоснующий выигрыш здесь, в основном, не из-за разного подхода к срезу в этих запросах (за исключением Д), а из-за кэширования цен на каждый день.

Как только цены станут устанавливаться в разное время дня (периодичность с точностью до секунд), вам потребуется считать их на время каждого документа, то есть очень много раз, вся тяжесть запроса (А) перейдет в первый запрос пакета и разница с запросом (В) станет меньше. В запрос (Б) я не верю: там и в первом запросе тэта соединение и во втором. Не верю в (Г).

Получается, я был не совсем прав, говоря о том, что для выигрыша (В) или (Д) нужно больше записей в РС, дело больше в количестве продаж номенклатуры в день, ну или в периодичности регистра.

Очищая все эти запросы от шелухи (то есть ставя их в равные условия), получаем ключевой вопрос сравнения подходов (А) и (В): что выгоднее - использовать агрегат "максимум" и записать период цены во временную таблицу, а затем запросом по сверхселективному индексу извлечь цену или использовать второе тэта соединение? Думаю, когда записей станет больше и больше, (В) станет проигрывать, Остается (Д) - вычисления (их еще можно подкрутить, использовать функцию подсчета остатка) против подсчета максимума и записи во временную таблицу. Меня в свое время удивило, что подсчет максимума при наличии индекса по соответствующему полю его не использует. Если это так в каких-либо СУБД, то (Д) - в любом случае проигрывает.

Собственно, таких размышлений мне и не хватало, чтобы, не соглашаясь с обоснованием, в целом согласиться с выводами статьи.

По поводу конкурса на придумывания лучших запросов, чем (А) и (В) могу сказать, что то, что предложено в (25) - это своего рода читерство. Чтобы превзойти такой запрос как (А) в общем каким-либо новым хитрым способом нужны условия (а они бывают в жизни), когда записей в РС гораздо больше. Если согласуем такие условия - могу попробовать...
41. randomus 235 19.02.21 12:49 Сейчас в теме
(37) Согласен на ваши условия. Попробуйте.

Вообще, конечно, я согласен - мое исследование однобокое и неполное - границы применимости неплохо было бы определить.

Кстати, тот факт, что я отключил параллелизм, почему-то никто не отметил. Но в реалиях-то он есть, и какие-то запросы параллелятся лучше, какие-то хуже. Тоже надо исследовать, если по хорошему.

Тета-соединения в варианте Б меня тоже смущали, поэтому он и вызывал недоверие. Но, как ни странно, в моих условиях показал себя хорошо
44. randomus 235 23.02.21 22:25 Сейчас в теме
(25) Наконец дошли руки запустить эти запросы на первоначальном стенде.

Сразу только период 6 мес.:

1) 16 сек. - весьма неплохо. Но запрос не один - есть коррелированный.
2) 22.3 сек. - улучшенный мой (В) вариант, за счет доп. отбора в соединении.
3) 46.5 сек. - результат улучшен, математику оптимизировали.

Ну в общем, 2-й запрос удовлетворяет условиям конкурса.
Если других вариантов не будет, признаем его победителем.

Отмечу, что 1-й запрос - очень элегантное решение, мне понравилось. По сути, 1-й и 2-й запрос делают одно и тоже, но во втором приходится перебрать гораздо больше строк. И исправить без коррелированного запроса никак не получается. @ildarovich - отдельное спасибо за дельные комментарии.
27. Serg O. 202 18.02.21 08:57 Сейчас в теме
(24) вы не совсем правы
установки цен могут (и идут!) каждый (рабочий, хотя бы) день

и да, товаров может быть намного больше 30-50 тыс. товаров
и умножаем это на 5-10 и более типов "базовых" цен!

тогда за месяц уже 1-1,5 млн. записей будет по 1 типу цен!
т.е. 5-15 млн. в "нашей реальности"

анализ на 1,5 тыс. наверное будет отличаться от 1,5 млн.
(и SQL планировщик иногда сам "решит" как лучше)
условия в соединении таблиц - вообще зло... и "не рекомендуется 1С"

на "нашей" базе УТ - запрос А за 1 месяц (январь 2021) - 66 сек - результат 18 359
если заменить Документ.ПродажаТовара -> Документ.РеализацияТоваровУслуг

и ошибка в запросе А - деление на 0 в поле Скидка
100 * (ЦеныНоменклатуры.Цена - РеализацияТоваровУслугТовары.Цена) / ЦеныНоменклатуры.Цена

пришлось заменить на условие
выбор когда ЦеныНоменклатуры.Цена>0
тогда 100 * (ЦеныНоменклатуры.Цена - РеализацияТоваровУслугТовары.Цена) / ЦеныНоменклатуры.Цена
иначе -100
конец
30. randomus 235 18.02.21 09:50 Сейчас в теме
(27)
установки цен могут (и идут!) каждый (рабочий, хотя бы) день

зачем тогда нужен срез последних?
31. Serg O. 202 18.02.21 09:55 Сейчас в теме
(30) цены (для примера) могут расти... а реально меняются вверх-вниз!

и задача тестовая (которая в запросе А) не на срез последних на конец периода...
а на получение продаж со скидкой > 10%

+ документы часто могут перепроводить / менять цены "задним числом"
и нужны цены на старую дату постоянно
26. Serg O. 202 18.02.21 08:43 Сейчас в теме
согласен с ildarovich, надо массивы побольше анализировать
1,5 -3 тыс записей в регистре это маловато...

Сделайте установки на каждый (рабочий, хотя бы) день
и да, товаров надо побольше 30-50 тыс. товаров
тогда за месяц уже 1-1,5 млн. записей хотя бы будет
это "ближе" к реальности...

для случайности, можно для теста цены +1р. на каждый день сделать
или по курсу $ например сделать за период
(доллар падает, цены растут вопреки логике?!)

кстати группировка хоть и "накладнее", но "сворачивает" лишние записи...
и без неё иногда не обойтись, + группировка делает доп.индексацию в ВТ
только это делается по всем полям группировки! а их "слишком много" вроде бы
гляда на запрос Г и Д не очень понятно... зачем там поле НомерСтроки ?

и да, большой + за проделанную работу, очень интересная статья
43. avega67 23.02.21 17:38 Сейчас в теме
Замечательная статья. И подана тоже очень хорошо.

По варианту "Б" только, по-моему, во 2-ом запросе пакета при формировании врем.таблицы ВТ_ПериодыЦен нужно:
КОНЕЦПЕРИОДА(ЕСТЬNULL(МИНИМУМ(ЦеныЗаПериод_Конец.Период), &КонецПериода), ДЕНЬ) КАК КонецПериода
Оставьте свое сообщение

См. также

Программные перечисления, ч.2: приемы кэширования при разработке Промо

Универсальные функции Механизмы платформы 1С Запросы Платформа 1С v8.3 Бесплатно (free)

Все знают, что такое кэш, и зачем он нужен. Но в 1С разработчик обычно использует кэширование только на уровне конфигурации, а в какой-нибудь обработке скорее ломает голову над запросом - как получить все данные за один заход... Хочется рассказать о том, как можно добиться хороших результатов с стратегией "разделяй и властвуй".

30.10.2017    29240    unichkin    18    

Новые возможности языка запросов в платформе 8.3.20

Запросы Платформа 1С v8.3 Запросы Бесплатно (free)

С платформы 8.3.20 анонсировали ряд изменений в языке запросов, с которыми интересно было повозиться на практике, что и было проделано. Результатом этих изысканий решил поделиться с вами.

27.09.2022    5142    zeltyr    17    

Партицированная дисциплина программиста в 1С

HighLoad оптимизация Механизмы платформы 1С Запросы Платформа 1С v8.3 Бесплатно (free)

Почему при росте объемов базы 1С все становится медленней, даже если все индексы правильно сделаны? В статье на простом примере с регистром сведений показана причина и как этого избежать. Кто виноват больше, 1С или MS SQL решать Вам :)

20.09.2022    1043    1CUnlimited    2    

Аналог PIVOT в запросе 1С (как выполнить транспонирование таблицы в запросе 1С) Промо

Запросы Платформа 1С v8.3 Бесплатно (free)

В статье показывается простой метод реализации аналога оператора PIVOT в запросе 1С без использования соединений.

12.12.2020    7201    Eugen-S    25    

Делаем свой интервальный регистр в ЗУП

Механизмы типовых конфигураций Запросы Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Бесплатно (free)

В статье, на примере реальной практической задачи попробуем снова погрузиться в одну из самых совершенных типовых конфигураций. Будем использовать механику интервальных регистров, правильно писать данные в такие регистры и правильно читать их.

09.09.2022    869    vazelin    4    

Ускорим проведение в 1С:Управление холдингом

HighLoad оптимизация Запросы Платформа 1С v8.3 1С:Управление холдингом Бесплатно (free)

В 1С:Управление холдингом есть "нехороший" запрос, который съедает значительную часть времени проведения документов. Если его подправить, то проведение заметно ускорится.

10.08.2022    4046    sapervodichka    54    

Порядковый номер в запросе. Нумерация строк в системе 1С

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данной статье будет описано, как в системе 1С присваивается порядковый номер в запросе, то есть происходит нумерация строк запроса. Будет сформирована некая универсальная задача, после чего будет предложен код запроса, который решит задачу и будет нумеровать строки.

02.08.2022    935    Koder_Line    10    

Как сделать запрос на изменение данных Промо

Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

В статье приведены особенности внутренней архитектуры и примеры работы с расширением языка запросов 1С.

01.06.2018    41017    m-rv    23    

Обход по группировкам в запросе, соединение таблиц, параметры в запросе, выгрузка прайс-листа в Excel, PDF, Docx, TXT

Запросы Файловые протоколы обмена (TXT, XML, DBF), FTP Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

В помощь начинающим программистам. Использую обработку из предыдущей моей публикации для разработки выгрузки Прайс-листа в Excel, PDF, Docx, TXT. Рассмотрю, как работает обход результата запроса ПоГруппировкам (релиз платформы 1С:Предприятие 8.3 (8.3.20.1674), самописная конфигурация).

18.07.2022    977    Pproksima    2    

Экспертный кейс. История расследования одного небыстрого закрытия месяца в 1C:ERP. Пример неочевидных путей расследования в виде детективной истории

HighLoad оптимизация Механизмы платформы 1С Запросы Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

В данной статье хотим рассказать об одном нашем непростом расследовании, в котором удалось собрать сразу несколько проблем на разных уровнях инфраструктуры заказчика и изначальной методологии ведения учета. Само расследование в какой-то момент стало напоминать детективную историю, с роялями в кустах, ошибками платформы, странным поведением пользователей и магическим поведением хорошо знакомых механизмов. Но мы реалисты, поэтому все проблемы были выявлены и устранены ;)

11.07.2022    4349    it-expertise    27    

Выразить число как строку и дату как строку в запросе Промо

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Предлагается новый и более компактный метод преобразования даты и числа в строку в запросе

22.02.2015    142766    ildarovich    79    

Кратность в Юанях (CNY) 10 и 1

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Обратите внимание на обмены данными с Юанями. Кратность там меняется между 10 и 1, в зависимости от значения курса > 10 или < 10. Т.е. НЕ ВСЕГДА равна 1. А многие разработчики (в том числе и я) грешат, ставя Кратность = 1 по умолчанию в обменах и выгрузках. P.S. Идём на Восток, становимся хитрее.

10.06.2022    5602    sapervodichka    12    

Экспертный кейс. Расследование фатального замедления времени расчета себестоимости в 1С:ERP 2

HighLoad оптимизация Механизмы типовых конфигураций Запросы Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

При выполнении нагрузочного тестирования информационной системы на базе 1С:ERP для одного из клиентов с целью оценки возможности миграции системы на PostgreSQL и Astra Linux мы столкнулись с неприемлемым увеличением времени выполнения расчета себестоимости. Строго говоря, сценарий тестирования закрытия месяца не был выполнен вообще – он не укладывался в таймаут выполнения теста, 24 часа. По прошествии 18 часов всё ещё шло выполнение операции «Распределение затрат и расчет себестоимости». Более 16 часов выполнялся подэтап “Расчет партий и себестоимости. Этап. Расчет себестоимости: РассчитатьСтоимость”. Всё это время выполнялся запрос, который в текущей инфраструктуре клиента (СУБД MS SQL Server) выполняется чуть более 3 минут на аналогичных данных.

25.03.2022    4437    it-expertise    92    

Экспертный кейс. Расследование деградации производительности системы. Проведение документа “Поступление товаров и услуг” (1С:ERP 2)

Механизмы платформы 1С Запросы HighLoad оптимизация Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

В ходе проведения нагрузочного тестирования одним из наших клиентов была выявлена сильная деградация производительности системы в целом и, в частности, выполнения ключевой операции “Проведение документа поступление товаров и услуг” в течение выполнения теста. Согласно данным подсистемы БСП “Оценка производительности”, время выполнения ключевой операции “Проведение документа поступление товаров и услуг” возрастало в процессе тестирования с 15-20 секунд в начале тестирования до 150-200 секунд в его финале.

02.03.2022    3396    it-expertise    47    

Расчет хэш-функции в запросе Промо

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Показано, как рассчитать в запросе значение хэш-функции для поля, имеющего тип "строка". Приведены результаты испытаний предложенного приема и несколько примеров его использования при решении конкретных практических задач.

20.03.2015    57591    ildarovich    39    

Задача по 1С - в базе данных есть таблица движения товара, пишем запрос для определения среднего значения остатка товара

Запросы Платформа 1С v8.3 Запросы Бесплатно (free)

В базе данных есть таблица движения товара, плюс означает, что товар пришел на склад, минус означает, что товар выбыл со склада: Необходимо написать запрос на 1С или SQL (по желанию), который вернет среднее значение остатка товара за январь 2021 (с 1 по 31). В результате должно получиться ProdID 1 = 1.58 ProdID 2 = 0.77

01.03.2022    1502    Greamdevil    3    

Генерация простых чисел в запросе (SQL) и сравнение производительности

Запросы Платформа 1С v8.3 Бесплатно (free)

Пишем запрос по генерацию последовательности простых чисел на языке запросов 1С и SQL.

09.01.2022    1088    AtamanovYS    0    

Заметки по SQL 4: Преобразование в запросе строки в дату одним выражением

Запросы Платформа 1С v8.3 Россия Бесплатно (free)

На "Инфостарте" есть несколько статей, описывающих преобразование строки в дату. Описанное в них преобразование осуществляется в несколько запросов и имеет сложные для понимания выражения. В статье описано относительно простое выражение в запросе, преобразующее строку в дату.

10.12.2021    1257    IVC_goal    17    

Сложные запросы в динамическом списке или как не надо писать запросы для них Промо

Запросы Платформа 1С v8.3 Бесплатно (free)

Задачи вывода в динамическом списке информации из смежных таблиц возникают очень часто, при этом программисты зачастую используют решения "в лоб", которые оказываются не совсем удачными.

24.07.2015    79557    Aleksey.Bochkov    39    

Готовые механизмы 1С: ЗУП, представления

Механизмы типовых конфигураций Запросы Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и Управление Персоналом 3.x Бухгалтерский учет Бесплатно (free)

Здесь будет храниться архив запросов, которые могут помочь разработчику правильно строить отчеты и получать данные в 1С: ЗУП. Статью буду периодически дополнять.

03.11.2021    4748    Margo462    19    

Работа с SQL. Шаблон общего модуля

Запросы Платформа 1С v8.3 Бесплатно (free)

Шаблон общего модуля для работы с MS/PG SQL из 1С.

21.10.2021    3367    mrChOP93    3    

Как читать чужой код? Часть 3. Разбор и доработка запросов

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Во всех вакансиях есть требование - умение читать чужой код. Но ни на одних курсах специально этому не учат. Чтобы устранить это противоречие, пишу данную статью. Рассмотрю случаи, в которых нам необходимо разбирать чужой код, поймём, чей код мы пытаемся разобрать, зачем и, главное, как. В статье описан личный опыт длиною в 18 лет начиная с версии платформы 7.7. Статья будет большой, набираемся терпения). Статья содержит в себе описание сценариев разбора кода, т.е. набор шагов. В статье не получится показать это на практике. Для этого планирую сделать онлайн или оффлайн курс, где на примерах будет показан разбор незнакомого кода. Статья разбита на 4 публикации для удобства изучения.

20.09.2021    3731    biimmap    32    

Распределение оплаты по товарам Промо

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Учебная задача. Оплата приходит по заказу. Требуется запросом распределить её по товарам. Практическая задача была сложнее. Упростил специально для иллюстрации. Сначала собираем в одну таблицу заказы и товары. Затем ОБЪЕДИНИТЬ ВСЕ с оплатами. Потом намазываем оплату на товар.

04.08.2014    19921    Трактор    4    

Еще один способ вычисления медианы запросом 1С

Запросы Платформа 1С v8.3 Платформа 1C v8.2 Бесплатно (free)

Вниманию сообщества предлагается еще один способ расчета медианы числового ряда одним пакетным запросом 1С.

09.08.2021    1892    direktorSan    0    

Временные таблицы запроса

Запросы Платформа 1С v8.3 8.3.14 Конфигурации 1cv8 Бесплатно (free)

Решил опубликовать эту маленькую статью для самых начинающих программистов 1С. Особенно для тех, кто часто сталкивается с отладкой запросов, а именно временных таблиц этих запросов. Сложность решений продуктов 1С сейчас заключается в том, что код нас уводит далеко вглубь общих модулей, перебрасывая из одного в другой и формируя в них временные таблицы запроса. Назад мы получаем кучу временных таблиц запроса, которые очень неудобно просматривать в отладчике. Для этого я и предлагаю свое ненавязчивое решение в виде расширения.

30.07.2021    2061    KonanSS    3    

Пример использования объекта "Схема запроса" в реальном проекте

Запросы Платформа 1С v8.3 Бесплатно (free)

Разберём решение задачи реального проекта: контекст, логика решения, само решение. Рассмотрим возможности объекта СхемаЗапроса.

03.06.2021    5109    maraton1185    32    

Объектная модель запроса "Схема запроса" - теория и примеры использования Промо

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В 8.3.5 в платформе 1С появился новый тип данных "Схема запроса". Статья о том, что он из себя представляет, зачем он вообще нужен, когда нужен и когда не нужен. И о том, как им пользоваться. Примеры создания текста запроса с нуля и изменение имеющегося запроса.

12.10.2014    93667    ekaruk    85    

Разбиение запросом записей периодического регистра сведений по интервалам

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Доброго времени суток, коллеги. У меня возникла задача - разбить запросом записи периодического регистра сведений по интервалам. Возможно, кому-то будет интересно решение подобной задачи. Покажу решение на примере регистра "История изменения уровней", в моем случае в нем можно для каждого элемента из справочника "Должности" задать уровень на любой период. Для примера использовал каркасную конфигурацию.   

22.12.2020    1834    Andrei_Ivanov    3    

Программное создание корректировочного счета-фактуры выданного в УПП 1.3

Математика и алгоритмы Механизмы типовых конфигураций Запросы Платформа 1С v8.3 1С:Управление производственным предприятием Россия Бухгалтерский учет НДС Бесплатно (free)

Данный функционал можно использовать, например, в процессе оформления возвратов от поставщика (корректировка реализации по согласованию сторон) при автоматическом создании корректировок реализации по документам поставщика, он позволяет массово создать корректировочные счета-фактуры в УПП 1.3. При создании документа из первичного счета-фактуры выданного в новый корректировочный счет-фактуру выданный копируются значения свойств.

17.12.2020    990    ksnik    0    

Имитация sql выражения LIMIT в запросе 1С

Запросы Платформа 1С v8.3 Бесплатно (free)

Всем известно, что в SQL синтаксисе есть выражение LIMIT. Очень полезное выражение для постраничной навигации. Но его нет в запросах 1С. Кто-то может сказать, что есть ПЕРВЫЕ, но ПЕРВЫЕ не подходит для постраничной навигации. Рассмотрим в статье, как можно имитировать LIMIT в запросах 1С.

08.12.2020    2683    opx    50    

Самоучитель языка запросов 1С. Промо

Запросы Платформа 1С v8.3 Запросы Бесплатно (free)

Сервис для изучения запросов 1С: "Консоль изучения запросов 1С:Предприятие 8". Теперь и с конструктором запросов!

07.05.2013    119954    bpc222    327    

Итоги по объединенной совокупности группировок в запросе

Запросы Платформа 1С v8.3 Бесплатно (free)

Способ формирования итогов в запросе по совокупности группировок, объединенных в единый набор, при помощи функции АВТОНОМЕРЗАПИСИ.

18.11.2020    8885    antonivan    21    

Кадровые данные сотрудников ЗУП 3.1 в запросе

Запросы Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Бесплатно (free)

Получение кадровый данных сотрудников в запросе при помощи функции КадровыйУчет.СоздатьНаДатуВТКадровыеДанныеСотрудников().

26.10.2020    5650    Danila7Zz    4    

Работаем с датами в запросе Промо

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

Понадобилось в запросе выполнить некоторые операции с датами: - посчитать дату оплаты в банковских днях; - собирать строки, в которые должны были входить даты, точнее строковые представления дат в формате "ДФ=dd.MM.yyyy". Вот что из этого получилось.

30.03.2010    66394    alexk-is    39    

Учимся создавать http сервис (часть четвертая). Изучение метода POST http запроса (передача текстовых данных)

Запросы Платформа 1С v8.3 Бесплатно (free)

Пошаговое руководство по созданию http сервисов (часть четвертая). Изучение метода POST http запроса.

11.10.2020    25663    hpi    29    

Улучшенный конструктор запроса тонкого клиента (Infostart Toolkit)

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Конструктор запросов тонкого клиента появился в платформе с 8.3.5 обладает рядом недостатков, которые возможно исправить. Передача входных таблиц, исправление связей и другое

07.09.2020    7729    Evg-Lylyk    21    

Как удалить из выборки дубли по двум полям. Промо

Запросы Платформа 1С v8.3 Россия Бесплатно (free)

Как удалить из выборки дубли по двум полям. Искал ответ в сети, ничего найти не смог, пришлось делать самому, возможно кому – то это пригодится.

15.11.2013    21379    Petr54-ru    22    

Меры центральной тенденции (вычисление среднего) в запросе 1С

Запросы Платформа 1С v8.3 Бесплатно (free)

Меры центральной тенденции (вычисление среднего) в запросе 1С: * Среднее арифметическое * Среднее гармоническое * Среднее квадратическое * Среднее усеченное * Среднее винсоризованное * Медиана * Мода

31.08.2020    1775    parcan    6    

Поблочная обработка таблицы. Обзор решений

Универсальные функции Запросы СКД Платформа 1С v8.3 Бесплатно (free)

8 способов реализации повседневной актуальной задачи, готовый код

25.02.2020    2988    Yashazz    21    

Нечёткий поиск "ПОДОБНО". Нюансы

Запросы Платформа 1С v8.3 Бесплатно (free)

Заметки о "ПОДОБНО" в языке запросов

23.02.2020    46527    Yashazz    31    

Отрицательные страховые взносы Промо

Механизмы типовых конфигураций Запросы Адаптация типовых решений Платформа 1С v8.3 1С:Зарплата и кадры бюджетного учреждения Бесплатно (free)

Иногда возникает необходимость рассчитать страховые взносы с отрицательной базы, но типовая зарплата сделать этого не позволяет. Предлагаю пример изменения запросов на релизе ЗКБУ 1.0.47.2 и всё будет считаться. Проверено на больших бюджетных организациях.

30.10.2012    12732    Nowa    25    

Нумерация строк в запросе методами платформы

Запросы Запросы Конфигурации 1cv8 Казахстан Бесплатно (free)

Простая реализация с помощью встроенных методов. Пригодится тем, кому нужно пронумеровать запрос без СКД и переборов.

09.01.2020    38976    user602678_maxipunchik    47    

Оптимизатор запроса. Часть первая

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Работа оптимизатора запроса является ключевой для обработки данных. Знание того, как оптимизатор выстраивает свою стратегию, отлично помогает при построении запросов.

23.12.2019    13069    darkdan77    21    

Полезные сведения о языке запросов 1С 8.2 Промо

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Украина Бесплатно (free)

В статье приведены полезные приемы при работе с запросами 1С v.8.2, а также сведения, которые не так хорошо известны о языке запросов. Я не стремлюсь дать полное описание языка запросов, а хочу остановиться лишь на некоторых моментах, которые для кого-то могут быть полезны.

10.12.2012    375855    fpat    84    

Расчет медианы и квартилей для дискретного ряда запросом

Запросы Платформа 1С v8.3 Бесплатно (free)

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

22.11.2019    12855    relines    7    

Как передать IP адрес, который вызвал HTTP запрос в 1C (для веб-сервера Apache)

Запросы Платформа 1С v8.3 Бесплатно (free)

Столкнулся с задачей получения IP адреса, который вызывает http сервис 1С. Итак, решение:

22.11.2019    15885    Sibars    19    

Группировка данных в запросе (СГРУППИРОВАТЬ ПО [ГРУППИРУЮЩИМ НАБОРАМ], ИТОГИ ПО [ОБЩИЕ])

Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

Для группировки данных в языке запросов 1С существуют конструкции СГРУППИРОВАТЬ ПО [ГРУППИРУЮЩИМ НАБОРАМ], ИТОГИ ПО [ОБЩИЕ]. Для новичков назначение этих конструкций не всегда очевидно, попробуем разобраться на примерах, для чего предназначена каждая из них и в чем отличие от аналогичных конструкций в языке SQL.

19.09.2019    56343    sertak    17