Как стать автором
Обновить

Комментарии 21

Еще бы планы запросов, цены бы не было
Очень интересно!
А на форум 1С не писали про такое решение?
Уже почти: http://infostart.ru/public/568299/ ;)
Спасибо!
http://infostart.ru/public/568299/
Еще бы по русски (на языке 1с) написать запрос — тоже цены бы не было.
Так ведь почти один к одному…
К тому же язык запросов 1С двуязычен — писать можно как на русском, так и на английском.
Автор молодец, наглядный пример оптимизации 1С!
Но 1С-совцам лучше дать универсальную процедуру на языке 1С, которая для любой пары таблиц будет генерировать запрос распределения — это буде им проще для применения, чем каждый раз вникать в строгость неравенств по OrderTop и OrderBottom.
НЛО прилетело и опубликовало эту надпись здесь
Подозреваю что из за переложения с 1С, там именно аналогичным оператором в тексте запроса это делается, и не припомню чтобы там аналоги IF были.
ВЫБОР КОГДА <Условие> ТОГДА <Выражени1>
ИНАЧЕ <Выражение2>
КОНЕЦВЫБОРА

Алгоритм перебора может написать кодом или псевдокодом? Есть предположение что использовался двойной цикл и сложность алгоритма n^2. Но данные имеют структуру поэтому можно заменить на алгоритм сложности n*log n

шринк и другие необходимые процедуры


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

Это категорически неверно — исключайте шринк из обслуживания и вообще забудьте о том, что его можно делать регулярно. Он нужен, если вы единоразово зачищаете базу от большого количества данных — переносите часть данных в отдельную базу, готовите тестовый стенд, избавляетесь от исторических данных и т.п. Только в этом случае шринк действительно можно использовать, чтобы уменьшить место, занимаемое файлами базы данных.

Шринк же на регулярной основе — это классический выстрел в ногу.
Почему «выстрел в ногу»?
Если базу не шринкуешь, то место переиспользуется
Потому что шринк приводит к: а) фрагментации — данные ужимаются, поэтому вместо красивых последовательных страниц ваши данные начинают распихиваться по любым свободным местам базы, негативные последствия фрагментации, надеюсь, понятны; б) затратам на рост — в базе не остается свободного места, и когда вы пишете туда новые данные, сиквел сначала обратно расширяет файлы, что сказывается на производительности, причем, если ваш сервер настроен неверно — достаточно сильно может сказаться.
угу. админы просто советы такие дают. не нравится им. как и с логами не разобравшись — секут. хотя эти файлы иногда важнее файла данных…
Немного повникал в алгоритм, как понимаю задача сводится к следующей: берем товар X, выкладываем в ячейку А по мере наполнения переходим к следующей, затем выкладываем товар Y и т.д. пока все товары не разложены.

Алгоритмически это решается в один проход. Никаких лишних переборов не надо.

ИМХУ без SQL эта задача еще быстрее должна решаться, скорее всего тормоза у автора были в чем-то совсем другом, что просто исчезло при переписывании с нуля. Возможно какая-то специфика 1С, я в ней не силен.

PS Первый запрос затестил: два Table scan, т.е. те самые лишние переборы, с которомы боролся автор.
Желающим посмотреть планы
create table #Cells (Cell char(1), Qty int)
insert into #Cells (Cell, Qty) values ('A', 10)
insert into #Cells (Cell, Qty) values ('B', 1)
insert into #Cells (Cell, Qty) values ('C', 5)
insert into #Cells (Cell, Qty) values ('D', 8)

select 
	t1.Cell, 
	t1.Qty, 
	ISNULL(sum(t2.Qty),0)+1 as OrderBottom, 
	ISNULL(sum(t2.Qty),0)+t1.Qty as OrderTop
from #Cells as t1
	left join #Cells as t2 
		on t1.Cell > t2.Cell
Group by 
	t1.Cell, 
	t1.Qty

drop table #Cells
Сканирование временных таблиц — это нормально.
Может просто индекса нет чтобы его использовать.
Вы попали в точку. На специализированном форуме (ссылка выше), где была размещена та же статья, автору указали на это несоответствие.
В том подмножестве T-SQL, которое реализовано в 1С нет, например, оконных функций, которые в этой задаче позволяют быстро посчитать нарастающий итог — это два первых запроса. Также нет и RowNumber(), который помог бы третий запрос оптимизировать. Поэтому как будто все должно было быть наоборот: запрос должен был тормозить (там n^2), а код — снизить затраты до n. Как автор получил прямо противоположный результат — можно только догадываться.
В статье действительно больше лирики, чем физики.
Я тоже однажды написал что-то подобное, но это было связано с распределением товарных остатков из двух регистров. Упрощённо, в одном регистре — измерения по складам и партиям, в другом — склад и серийные номера, и нужно было распределить серийные номера по партиям в пределах одного склада. Делалось однократно для переноса остатков между базами, скорее just for fun, чем для реального ускорения. Пришлось делать несколько временных таблиц, которые хитрым образом соединялись сами с собой. Уже, наверно, пару лет такого делать не приходилось.
Первый подобный приём подсмотрел в книжке Габец и Гончарова «Простые примеры разработки». И там был пример: Как одним запросом получить таблицу расхождений курсов взаиморасчетов. Там как раз можно посмотреть логику объединения таблиц, чтобы получить нужное распределение.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории