gifts2017

Опять эти запросы...

Опубликовал mr. Script (m..adm) в раздел Программирование - Практика программирования

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

1. Генерация диапазона чисел запросом.

Данный метод уже не раз был описан. Повторюсь с некоторыми своими комментариями.

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

ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1;

ВЫБРАТЬ ВТ0.Ч + ВТ1.Ч*2 + ВТ2.Ч*4 + ВТ3.Ч*8 КАК Число
ИЗ ВТ КАК ВТ0, ВТ КАК ВТ1, ВТ КАК ВТ2, ВТ КАК ВТ3

В запросе выбираем числа 0,1 и помещаем во временную таблицу ВТ. Последующее соединение-сочетание таких таблиц образует необходимую выборку. Диапазон чисел, который сгенерирует такой запрос, будет равняться M в степени N, где M - количество чисел в системе счисления, N - количество соединяемых таблиц. В нашем примере имеем систему счисления с двумя числами и  базовая таблица соединяется "сама с собой" 4 раза, поэтому результат получим в 16 чисел. Для получения большего диапазона чисел необходимо увеличивать количество соединений базовой таблицы, или же изменить систему счисления. 

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

ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000 КАК Число
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3

Этот запрос позволяет сформировать выборку чисел от 0 до 9999. Для увеличения диапазона выбранных чисел увеличиваем количество соединений базовой таблицы.

2. Генерация диапазона дат запросом в заданном периоде.

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

Можно, например, получить выборку дат из регистра сведений "Курсы валют":

 

ВЫБРАТЬ РАЗЛИЧНЫЕ
КурсыВалют.Период КАК Дата
ИЗ  РегистрСведений.КурсыВалют КАК КурсыВалют
ГДЕ КурсыВалют.Период МЕЖДУ &НачалоПериода И &КонецПериода


или же получить выборку периодов из регламентированного календаря (если такой есть в конфигурации):

 

ВЫБРАТЬ Рег.ДатаКалендаря КАК Дата
ИЗ РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Рег
ГДЕ Рег.ДатаКалендаря МЕЖДУ &НачалоПериода И &КонецПериода


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

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

 

ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода,День),День,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) КАК День
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3
ГДЕ ДОБАВИТЬКДАТЕ(&НачалоПериода,День,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) <= НАЧАЛОПЕРИОДА(&КонецПериода,День)


Этот запрос позволяет сделать выборку всех дней с НачалоПериода по КонецПериода. Максимальное количество дней для этого запроса составляет 10000 (27 лет).

Такой запрос легко трансформируется в выборку секунд, минут, часов, лет или кварталов путем замены параметра "День" на "Секунда","Час","Минута","Год" или "Квартал". Выборка разных кварталов, например, будет выглядеть так:

 

ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода,Квартал),Квартал,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) КАК Квартал
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3
ГДЕ ДОБАВИТЬКДАТЕ(&НачалоПериода,Квартал,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) <= НАЧАЛОПЕРИОДА(&КонецПериода,Квартал)


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

3. Остатки товаров и срезы последних запросом на каждый день.

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

Например в теме http://infostart.ru/public/306536/ пользователем ildarovich был предложен следующий вариант получения остатков товаров на каждый день:

ВЫБРАТЬ РАЗЛИЧНЫЕ
    КурсыВалют.Период
ПОМЕСТИТЬ Дни
ИЗ
    РегистрСведений.КурсыВалют КАК КурсыВалют
ГДЕ
    КурсыВалют.Период МЕЖДУ &НачалоПериода И &КонецПериода
;

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

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

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

Кто выполнял оптимизацию запроса списания по партиям в УТП, УПП, возможно, сталкивались с проблемой, когда этот запрос выполняется очень долго. В моей практике у некоторых клиентов этот запрос иногда даже "зависал" или порождал длительную транзакцию.

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

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

Ближе к делу... Эксперимент

Беру предложенный вариант получения дневных конечных остатков по товарам на складах пользователя ildarovich и делаю из него следующий запрос для тестирования:

ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода,День),День,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) КАК Период
ПОМЕСТИТЬ Дни
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3
ГДЕ ДОБАВИТЬКДАТЕ(&НачалоПериода,День,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) <= НАЧАЛОПЕРИОДА(&КонецПериода,День);

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

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

ВЫБРАТЬ СУММА(ВТИтог.КоличествоКонечныйОстаток) КАК КоличествоКонечныйОстаток
ИЗ ВТИтог КАК ВТИтог

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

Для сравнения использую следующий запрос получения остатков на конец дня:

ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода,День),День,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) КАК Период
ПОМЕСТИТЬ Дни
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3
ГДЕ ДОБАВИТЬКДАТЕ(&НачалоПериода,День,ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000) <= НАЧАЛОПЕРИОДА(&КонецПериода,День);

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

ИНДЕКСИРОВАТЬ ПО
    Движения.Номенклатура,
    Движения.Период;

ВЫБРАТЬ
    ВН.Номенклатура,
    ВН.Период,
    ЕСТЬNULL(ВТД.КоличествоКонечныйОстаток, 0) КАК КоличествоКонечныйОстаток
ПОМЕСТИТЬ ВТИтог
ИЗ
    (ВЫБРАТЬ РАЗЛИЧНЫЕ
        Дни.Период КАК Период,
        ВТД.Номенклатура КАК Номенклатура
    ИЗ
        Дни КАК Дни,
        ВТД КАК ВТД) КАК ВН
        ЛЕВОЕ СОЕДИНЕНИЕ ВТД КАК ВТД
        ПО ВН.Номенклатура = ВТД.Номенклатура
            И ВН.Период >= ВТД.Период
            И (ВТД.Период В (ВЫБРАТЬ МАКСИМУМ(ВП.Период)
                ИЗ ВТД КАК ВП
                ГДЕ ВП.Номенклатура = ВТД.Номенклатура
                    И ВН.Период >= ВП.Период));

ВЫБРАТЬ СУММА(ВТИтог.КоличествоКонечныйОстаток) КАК КоличествоКонечныйОстаток
ИЗ  ВТИтог КАК ВТИтог

Оба запроса выполняю в консоли запросов 10 раз и фиксирую время выполнения

Замер Запрос 1 Запрос 2
1 4,609 4,297
2 4,531 4,297
3 4,563 4,328
4 4,609 4,297
5 4,703 4,313
6 4,578 4,454
7 4,469 4,297
8 4,484 4,313
9 4,515 4,281
10 4,703 4,297

Среднее,с.

4,5764 4,3174

Итоги тестирования показывают небольшой прирост производительности, чуть больше 5%. Однако эти замеры производились под полными правами. Можете проверить результаты под пользователем с ограниченной учетной записью на регистр "ТоварыНаСкладах", думаю, прирост производительности предлагаемого запроса будет еще выше.

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

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

За базу возьмем вариант получения цен номенклатуры на дату продажи товара предложенный в теме http://infostart.ru/public/77568/ пользователем _also . Его запрос выглядит так:

 

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

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

ИНДЕКСИРОВАТЬ ПО
    Номенклатура,
    Дата,
    Контрагент
;

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

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

ИНДЕКСИРОВАТЬ ПО
    Номенклатура,
    Дата,
    Контрагент,
    Период
;

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


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

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

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

ИНДЕКСИРОВАТЬ ПО
    Номенклатура,
    Дата;

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

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

Мой запрос в данной реализации выглядел бы так:

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

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

 

Выполняю 10 раз подряд каждый запрос и фиксирую время выполнения:

Замер Запрос 1 Запрос 2
1 0,875 0,313
2 0,844 0,265
3 0,844 0,266
4 0,843 0,297
5 0,844 0,282
6 0,859 0,281
7 0,844 0,297
8 0,843 0,281
9 0,984 0,283
10 0,844 0,297
Среднее, с. 0,8624 0,2862

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

4. Генерация нумерованных комбинаций свойств товара в запросе

На создание запроса, который для указанного перечня товара и набора свойств сгенерирует все возможные комбинации из этих свойств,  подтолкнула тема http://infostart.ru/public/295343/ . Интересная задачка для разминки серого вещества.

Дабы не тратить уйму времени на универсальный запрос, оговорим, что в исходных данных может быть только два вида свойств. Ну, и чтобы запрос не был совсем детским, добавим изюминку - необходимо пронумеровать созданные пары свойств в пределах каждого товара.

К примеру, имеем мы на входе перечень товара с указанием их свойств:

Товар Свойство Значение свойства
Товар А Материал обшивки Сталь
Товар А Материал обшивки Алюминий
Товар А Материал обшивки Пластмасса
Товар А Материал основания Сталь
Товар А Материал основания Алюминий
Товар Б Материал обшивки Сталь
Товар Б Материал обшивки Алюминий
Товар Б Материал основания Алюминий
Товар Б Материал основания Сталь

Выберем эти данные запросом и поместим во временную таблицу ВТ, эта таблица и будет исходными данными для запроса:

ВЫБРАТЬ "Товар А" КАК Товар, "Материал обшивки" КАК Свойство, "Сталь" КАК Значение
ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар А", "Материал обшивки"   ,"Алюминий"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар А", "Материал обшивки"   ,"Пластмасса"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар А", "Материал основания" ,"Сталь"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар А", "Материал основания" ,"Алюминий"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар Б", "Материал обшивки"   ,"Сталь"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар Б", "Материал обшивки"   ,"Алюминий"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар Б", "Материал основания" ,"Алюминий"
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ  "Товар Б", "Материал основания" ,"Сталь";

Далее выполним следующую запрос:

ВЫБРАТЬ
   
ВТ1.Товар КАК Товар,
   
ВЫБОР
        КОГДА
ВТ1.Свойство > ВТ2.Свойство
            ТОГДА КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ4.Значение) * МАКСИМУМ(Ит.Итог) + КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ3.Значение)
       
ИНАЧЕ КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ3.Значение) * МАКСИМУМ(Ит.Итог) + КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ4.Значение)
   
КОНЕЦ +1 КАК Вариант,
   
ВТ1.Свойство КАК Свойство,
   
ВТ1.Значение
ИЗ
   
ВТ КАК ВТ1
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ КАК ВТ3
        ПО ВТ1.Товар = ВТ3.Товар
            И ВТ1.Свойство = ВТ3.Свойство
            И ВТ1.Значение > ВТ3.Значение,
   
ВТ КАК ВТ2
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ КАК ВТ4
        ПО ВТ2.Товар = ВТ4.Товар
            И ВТ2.Свойство = ВТ4.Свойство
            И ВТ2.Значение > ВТ4.Значение,
    (ВЫБРАТЬ
И2.Товар КАК Товар, МАКСИМУМ(И2.Итог) КАК Итог
        ИЗ (ВЫБРАТЬ И1.Товар КАК Товар, КОЛИЧЕСТВО(РАЗЛИЧНЫЕ И1.Значение) КАК Итог
            ИЗ ВТ КАК И1
            СГРУППИРОВАТЬ ПО
               
И1.Товар, И1.Свойство) КАК И2
    СГРУППИРОВАТЬ ПО И2.Товар) КАК Ит
ГДЕ
   
ВТ1.Товар = ВТ2.Товар
    И ВТ1.Товар = Ит.Товар
    И ВТ1.Свойство <> ВТ2.Свойство
СГРУППИРОВАТЬ ПО
   
ВТ1.Товар,
   
ВТ1.Свойство,
   
ВТ1.Значение,
   
ВТ2.Свойство,
   
ВТ2.Значение
УПОРЯДОЧИТЬ ПО
   
Товар,Вариант, Свойство

И получим выборку товара с перечнем пронумерованных комбинаций свойств.

 

Товар Вариант Свойство Значение
Товар А 1 Материал обшивки Алюминий
Товар А 1 Материал основания Алюминий
Товар А 2 Материал обшивки Алюминий
Товар А 2 Материал основания Сталь
Товар А 4 Материал обшивки Пластмасса
Товар А 4 Материал основания Алюминий
Товар А 5 Материал обшивки Пластмасса
Товар А 5 Материал основания Сталь
Товар А 7 Материал обшивки Сталь
Товар А 7 Материал основания Алюминий
Товар А 8 Материал обшивки Сталь
Товар А 8 Материал основания Сталь
Товар Б 1 Материал обшивки Алюминий
Товар Б 1 Материал основания Алюминий
Товар Б 2 Материал обшивки Алюминий
Товар Б 2 Материал основания Сталь
Товар Б 3 Материал обшивки Сталь
Товар Б 3 Материал основания Алюминий
Товар Б 4 Материал обшивки Сталь
Товар Б 4 Материал основания Сталь

В двух словах, как работает запрос. Соедиение базовой таблицы товара смой с собой по товару и различным свойствам дает нам ведущую выборку - все сочетания свойств. Ведущая выборка образуется из ВТ1 и ВТ2. Дополнительные соединение к этим двум таблицам базовой таблицы товара ВТ3 И ВТ4 с проверкой на значения свойств дает возможность накапивать  в итоговой выборке нумерацию сочетаний свойств зеркально по данным таблицы ВТ1 и ВТ2. Таблица Итог необходима для определения максимального количества различных значений свойств для каждого товара, сочетание этого значения с накопительными данными по двум зеркальным веткам накопления дадут итоговый вариант сочетания свойств товара. 

На вход запроса можно подавать различное количество свойств и товаров, главное, чтобы видов свойств было только 2 в пределах одного товара.

5. Определение интервалов в запросе.

В продолжения раздела 3 статьи хотелбы привести еще один сравнительный эксперимент. Эксперимент будет заключаться в сравнительном анализе потраченного времени на построение интервалов в запросе двумя методами. Будем сравнивать скорость выполнения запроса с группировкой и запроса с паралельной фильтрующей выборкой.

Первый запрос:

ВЫБРАТЬ
   
Т1.Ч КАК НачалоИнтервала,
   
МИНИМУМ(Т2.Ч) КАК КонецИнтервала
ПОМЕСТИТЬ Темп
ИЗ
   
БазоваяТаблица КАК Т1
      ВНУТРЕННЕЕ СОЕДИНЕНИЕ БазоваяТаблица КАК Т2
      ПО Т1.Ч < Т2.Ч

СГРУППИРОВАТЬ ПО Т1.Ч;

УНИЧТОЖИТЬ Темп

Второй запрос:

ВЫБРАТЬ РАЗЛИЧНЫЕ
   
Т1.Ч КАК НачалоИнтервала,
   
Т2.Ч КАК КонецИнтервала
ПОМЕСТИТЬ Темп
ИЗ
   
БазоваяТаблица КАК Т1
     ВНУТРЕННЕЕ СОЕДИНЕНИЕ БазоваяТаблица КАК Т2
     ПО Т1.Ч < Т2.Ч
        И (Т2.Ч В
           
(ВЫБРАТЬ МИНИМУМ(ВНЗ.Ч)
             ИЗ
БазоваяТаблица КАК ВНЗ
             ГДЕ Т1.Ч < ВНЗ.Ч));

УНИЧТОЖИТЬ Темп

Второй запрос построен мною по тому же принципу, что запрос  в  разделе 3 статьи.

Для тестирования я написал обработку которая сформирует N-индексированных временных таблиц определенного размера и выполнит тестовый замер времени выполнения первого и второго запроса. 

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

Обработка производит поочерёдное выполнение правого и левого запроса с выборкой данных из каждой таблицы. Выполнение запросов производится по 5 раз по каждой временной таблице и выбирается наименьшее время выполнения каждого запроса - дабы немного исключить возможные временных всплески нагрузок на сервере. 

Тестирование производил на стареньком двухпроцессорном Supermicro-сервере на 8 ядрах Xeon 2.3 ГГц с 6 ГГб оперативной памяти и бюджетным  SSD. Сервер баз данных MS SQL 2012.

Результат тестирования:

В диаграмме эффективности я отобразил во сколько раз второй запрос выполняется быстрее от первого взависимости от объема выборки данных.

Я не эксперт, но для тех, кто хорошо разбирается в MS SQL привожу запросы сервера баз данных и их планы выполнения:

Первый запрос и план выполнения:

INSERT INTO #tt59 WITH(TABLOCK) (_Q_000_F_000, _Q_000_F_001)
SELECT
T1._Q_000_F_000, MIN(T2._Q_000_F_000)
FROM
#tt14 T1 WITH(NOLOCK)
INNER JOIN
#tt14 T2 WITH(NOLOCK)
ON (
T1._Q_000_F_000 < T2._Q_000_F_000)

GROUP BY T1._Q_000_F_000

Второй запрос и план выполнения:

INSERT INTO #tt59 WITH(TABLOCK) (_Q_000_F_000, _Q_000_F_001)
SELECT
DISTINCT
T1._Q_000_F_000, T2._Q_000_F_000
FROM #tt10 T1 WITH(NOLOCK)
INNER JOIN
#tt10 T2 WITH(NOLOCK)
ON ((
T1._Q_000_F_000 < T2._Q_000_F_000) AND T2._Q_000_F_000 IN
(SELECT
MIN(T3._Q_000_F_000) AS Q_001_F_000_
FROM #tt10 T3 WITH(NOLOCK)
WHERE (
T1._Q_000_F_000 < T3._Q_000_F_000)))

Собственно говоря, прирост производительности запроса без группировки очевиден.

Однако есть недостатки такого метода реализации. Если запустить обработку анализа запросов на файловой базе, то картина будет совсем противоположной.

Собственно говоря, все. 

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

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

Спасибо.

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Тест запросов
.epf 19,20Kb
08.12.15
3
.epf 19,20Kb 3 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. ivanov660 ivanov660 (ivanov660) 07.12.15 10:53
Использование в запросах виртуальной таблицы регистра накопления остатки и обороты зло.
2. Александр Воронов (ya.Avoronov) 07.12.15 12:10
А я наивно верю и жду, что 1С даст возможность делать такие вот примитивные запросы:
Выбрать ДиапазонДат.Дата
	Из ДиапазонДат(&НачалоПериода, &КонецПериода, День) КАК ДиапазонДат


Выбрать ДиапазонЧисел.Число
	Из ДиапазонЧисел(&НачЧисло, &КонЧисло, &Шаг) КАК ДиапазонЧисел
...Показать Скрыть


Или я один такой?
savostin.alex; +1 Ответить 1
3. Сан Саныч (herfis) 07.12.15 12:23
(2) ya.Avoronov, Я не жду.
Так как "нормальных" и универсальных решений этой задачи не существует.
Либо сабжевый костыльно-антиреляционный подход (материалы статьи, кстати, довольно вторичны и боянисты), либо табличку засылать (что тоже далеко не фонтан).
Оптимально было бы табличку генерить на стороне сервера БД хранимкой. Это было бы как раз нормальное решение. Но 1С на это не пойдет, т.к. это повышает стоимость кроссплатформенной поддержки.
4. Алексей Роза (DoctorRoza) 07.12.15 12:26
(1) ivanov660, это где Вы такое вычитали? А если статистика обновлена, индексы дефрагментированы все равно зло? Может так стоит говорить о РБ, хоть и с натяжкой?

Например в теме http://infostart.ru/public/306536/ пользователем ildarovich был предложен следующий вариант получения остатков товаров на каждый день:


Чувствую, но намечается нехилый батл! :)
5. Николай Пугачев (nickpugachev) 07.12.15 18:31
(4) DoctorRoza,
это где Вы такое вычитали? А если статистика обновлена, индексы дефрагментированы все равно зло? Может так стоит говорить о РБ, хоть и с натяжкой?

стоит пару раз увидеть конечный запрос в sql

в зависимости от потребностей быстрее может быть выборка остатков на начало и изменений на каждый день. но нужно смотреть по ситуации.
6. Яков Коган (Yashazz) 07.12.15 19:07
После Ильдаровича все такие публикации смотрятся как второсортный баян.
И насчёт виртуальной таблицы - согласен, зло почти всегда.
7. mr. Script (m..adm) 07.12.15 20:07
(6) Yashazz, Несколько вопросов. Ты кто такой? Ты построение запросов анализировал? Как относится к твоим бла-бла-бла о баянах?
8. Алексей Роза (DoctorRoza) 08.12.15 09:19
(5) nickpugachev, если Вы работаете с крупным производством, то, конечно же, разбирали основные типовые отчеты УПП 1.3. Например, ведомости (ВедомостьТоварыНаСкладах), то они все из виртуальных таблиц ОстаткиИОбороты. И это зло? "Сомневаюсь!" (Киселев). :) А если зло, то самое меньшее из! Хотя да, все по ситуации.
9. Анд Ск (and_sk) 08.12.15 10:01
чето перемудрено вроде

ВЫБРАТЬ
НАЧАЛОПЕРИОДА(Товар.Период, ДЕНЬ) КАК Дата,
Товар.КоличествоКонечныйОстаток
ИЗ
РегистрНакопления.ТоварыОрганизаций.ОстаткиИОбороты(&Нач, &Кон, Регистратор, , ) КАК Товар
10. mr. Script (m..adm) 08.12.15 10:23
(9) and_sk, что именно перемудрено?
11. Анд Ск (and_sk) 08.12.15 10:31
даты в отрыве от данных частные задачи
и мне кажется не требуют какогото особого подхода
решаются в порядке поступления))
12. mr. Script (m..adm) 08.12.15 11:02
(11) and_sk, да, в большинстве случаев так и есть. Но есть задачи как расчет среднесуточного остатка или оборачиваемости товара. В таких задачах надо все даты.
13. Сергей (ildarovich) 08.12.15 12:10
Не удержусь и покритикую. По задаче 3(остатки):

1) "Мой" запрос можно оптимизировать;
2) Направление оптимизации выбрано (по моему мнению) неверное;
3) Такое решение встречается часто, то есть новизны в предложенном решении нет.

Подробнее по пунктам:

1) Целью написания исходного запроса являлась компактность записи. Хотелось уложиться ровно в один запрос. Поскольку он появился в теме, где эта задача решалась 5-6 запросами в пакете. То есть оптимизация была отодвинута на второй план.
Для этого в качестве основной таблицы была взята таблица остатков и оборотов с разворотом по дням. Хотя на самом деле остатки реально используются (входят в сумму) только в первом дне периода. А в остальные дни используются только обороты. На этом можно сэкономить.

Для этого нужно взять таблицу остатков и оборотов не по дням, а в целом за период. Использовать только начальные остатки из этой таблицы. При этом можно ожидать, что отсутствующие в начале периода товары будут не отсутствовать вообще (если взять только остатки), а выводится нулями, если запросить (но не использовать) количество прихода и расхода. Поскольку период отчета обычно кратен периоду хранения итогов, можно ожидать, что эта таблица просто возьмется из рассчитанных итогов.
Кроме того, нужно будет взять таблицу оборотов по дням. Хотя кажется, что можно взять и движения, это будет неправильно. Предварительная группировка движений по дням сократит время на сравнение на попадание в диапазон дней.
Таблицы можно СОЕДИНИТЬ и получить тот же один запрос, но с двумя соединениями. Но НАДЕЖНЕЕ таблицы ОБЪЕДИНИТЬ перед соединением с датами.
В итоге получается такой запрос (на примере регистра Товары на складах):
ВЫБРАТЬ 0 КАК Х
ПОМЕСТИТЬ Разряд
ОБЪЕДИНИТЬ ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВЫБРАТЬ 9
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, (Р0.Х * 10 + Р1.Х) * 10 + Р2.Х) КАК Период
ПОМЕСТИТЬ ВТДаты
ИЗ
	Разряд КАК Р0,
	Разряд КАК Р1,
	Разряд КАК Р2
ГДЕ
	ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, (Р0.Х * 10 + Р1.Х) * 10 + Р2.Х) <= &КонецПериода
;

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

ОБЪЕДИНИТЬ ВСЕ

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

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

СГРУППИРОВАТЬ ПО
	Движения.Номенклатура,
	Даты.Период
...Показать Скрыть
В этом запросе нет лишних действий, именно его и нужно тестировать для сравнения. Он сохраняет суть исходного "моего" запроса: для нахождения промежуточных остатков накапливаются обороты. Именно так и работает нахождение остатков платформой, если остатки требуется рассчитать внутри периода итогов.

2) Почему кажется, что подход из статьи содержит лишние действия? - Сначала считаются остатки внутри периода итогов. Потом остатки интерполируются как срез последних на каждую дату. То есть для каждой находится дата последнего изменения. И соединением остаток берется из нее. Индекс (на построение которого тоже идет время) здесь помогает мало (в срезе последних регистра сведений он берется готовый). Кажется, что действия сложнее и их больше. Не на много, но больше. Плюс соединения, а не простая группировка.

3) Вот одна из ссылок: http://infostart.ru/public/101321/ . Можно еще много найти, если постараться.
myjob1c; Vlasenko.Oleg; Makushimo; kuzyara; Yashazz; artbear; +6 Ответить 7
14. Сергей (ildarovich) 08.12.15 13:12
+(13) По задаче 4:
Всего два свойства? - Но тогда все должно быть ГОРАЗДО проще!
Все комбинации получается сразу всего одним простым запросом:
ВЫБРАТЬ
	Инь.Товар,
	Инь.Значение КАК ЗначениеСвойства1,
	Янь.Значение КАК ЗначениеСвойства2
ПОМЕСТИТЬ Ответ
ИЗ
	ВТ КАК Инь
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ КАК Янь
		ПО Инь.Товар = Янь.Товар
			И Инь.Свойство < Янь.Свойство
...Показать Скрыть

Если варианты нужно пронумеровать, то
ВЫБРАТЬ
	Ответ.Товар КАК Товар,
	КОЛИЧЕСТВО(Слева.Товар) КАК НомерВарианта,
	Ответ.ЗначениеСвойства1,
	Ответ.ЗначениеСвойства2
ПОМЕСТИТЬ ОтветСНомеромВарианта
ИЗ
	Ответ КАК Слева
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Ответ КАК Ответ
		ПО Слева.Товар = Ответ.Товар
			И (Слева.ЗначениеСвойства1 < Ответ.ЗначениеСвойства1
				ИЛИ Слева.ЗначениеСвойства1 = Ответ.ЗначениеСвойства1
					И Слева.ЗначениеСвойства2 <= Ответ.ЗначениеСвойства2)

СГРУППИРОВАТЬ ПО
	Ответ.Товар,
	Ответ.ЗначениеСвойства1,
	Ответ.ЗначениеСвойства2
...Показать Скрыть
Если нужен ответ "в столбик", то
ВЫБРАТЬ
	Ответ.Товар,
	Ответ.НомерВарианта,
	Ответ.ЗначениеСвойства1
ИЗ
	ОтветСНомеромВарианта КАК Ответ

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	Ответ.Товар,
	Ответ.НомерВарианта,
	Ответ.ЗначениеСвойства2
ИЗ
	ОтветСНомеромВарианта КАК Ответ
...Показать Скрыть
Названия свойств также добавить ничего не стоит. Конечно, нумерация вариантов тут помедленнее, но это также легко ускорить, не прибегая к запутанному запросу из статьи. По сути взят универсальный метод из статьи "Запрос-комбинатор" как некая формула, выполнена подстановка (число свойств = 2), а упрощения (раскрытия скобок, приведение и прочее не сделаны). Вот и получился запрос-крякозябра.
А вообще исходная задача была и интересная и практическая. Без универсальности там было не обойтись.
15. Сергей (ildarovich) 08.12.15 13:22
+(13) "изюминки" во второй половине задачи 3 я не увидел. Если речь идет о замене соединения на запрос с конструкцией ГДЕ (Поле1, Поле2) В (Выбрать Поле1, Поле2 Из ...), то эффективность такой замены нужно тестировать на разных СУБД. Смотреть планы запроса. Повторы при замерах тоже настораживают. Результат (Выбрать Поле1, Поле2 Из ...) и индекс для поиска, возможно, в кэше оставался, что и давало прирост. Также непонятны причины появления двух разных цен одного типа на одну дату, которые по регистратору нужно разделять (МАКСИМУМ?ссылка). Кажется, такой вариант вообще должен быть еще при записи исключен.
16. Яков Коган (Yashazz) 08.12.15 16:35
(7) m..adm, по пунктам:
Ты кто такой?
Посетитель сайта "Инфостарт".*
Ты построение запросов анализировал?
Как минимум маловнятный вопрос. Построение - это которое программист 1С в коде делает? Текстом, конкатенацией, или объектной моделью запроса? А может, это которое 1С делает, когда в язык запросов СУБД транслирует? Или это вообще о работе планировщика речь? Увы мне, не смог понять...
Как относится к твоим бла-бла-бла о баянах?
А вот Ильдарович уже и ссылку подкинул, и объяснил. Грешен я, занят был, некогда мне было своё частное мнение детально разжёвывать.

*а вообще спасибо, посмеялся
17. mr. Script (m..adm) 08.12.15 17:06
(16) Yashazz, Ильдарович свои соображения изложил внятно, мне не жалко будет на такой подход человека потратить время на ответ, чуть позже после работы. Ну а ты то тут каким боком? Сказал о зле виртуальных таблиц заезженную тему и на этом усё? Как автору статьи, потратившему все-таки хороший кусок времени на ее изложение, печально слышать какие-то темы о баянах. Посему, если нет времени, нет желания отписывать или есть прочие у тебя дискомфорты, тогда чуть полем-полем, а потом лесом и подальше от этой темы. В противном случае по существу, без выделывания. Ок? Надеюсь моя мысль услышана. Спасибо.
18. Сергей (ildarovich) 08.12.15 17:14
(12) m..adm,
Но есть задачи как расчет среднесуточного остатка или оборачиваемости товара. В таких задачах надо все даты
На всякий случай замечу, что в статье Расчет средних по периодам в запросе - это элементарно! показано, как рассчитать среднедневной остаток вообще БЕЗ расчета остатков по дням.
19. mr. Script (m..adm) 08.12.15 23:12
(13) ildarovich, 1) Ваш запрос был взят для сравнительного примера. В разделе 3 статьи я получил небольшой процент прироста производительности своего запроса в сравнении с Вашим. Эти тесты я выполнил вручную в консоли запросов. На досуге найду время и проведу тесты с использованием обработки, которую я описал в разделе 5. Отпишу о результатах.
Относительно запроса, который Вы приводите как более оптимальный в этих комментариях. Меня терзают сомнения, что он более оптимален, т.к. в нем присутствует выборка из двух виртуальных таблиц регистра. И в случае, когда, дисковая система сервера баз данных оставляет желать лучшего, чтение двух наборов данных может дать дополнительную задержку. Думаю, выборки из одной жирной таблицы остатки-обороты тут достаточно, но этот момент также требует тестирования.
"Но НАДЕЖНЕЕ таблицы ОБЪЕДИНИТЬ перед соединением с датами" - тут немного смешно звучит, ведь "НАДЕЖНО" оно и в Африке надежно будь то запрос-объединение или соединение полной таблицы с выборочными данными.
"Направление оптимизации выбрано (по моему мнению) неверное" - Ваше мнение, спасибо. Я же в статье показываю что при реализации запроса с паралельным фильтрующим соединением в клиент-серверном варианте получаем значительный прирост быстродействия по сравнению с запросом с группировкой. Ключевым в этой реализации есть индексированная базовая таблица. На ее формирование уйдет время и ресурсы сервера, однако, затраты времени на формирование таблицы будут перекрыты выгодой от производительности запроса. Ресурсами сервера пренебрегаем, т.к. я рассматриваю эту тему, как вариант убыстрения выполнения запроса на больших объемах данных, а не минимизацию кода или потребления ресурсов. У Вас есть похожая статья, было бы интересно, сравнить результаты от выходы решений. Правда, мои тесты производились на числовых данных, на индексированных данных типа "дата", боюсь, будут другие результаты.
"Такое решение встречается часто, то есть новизны в предложенном решении нет." - поделитесь ссылочкой, а то я это решение из своей практики взял, а не с Googля.
Спасибо
20. mr. Script (m..adm) 08.12.15 23:14
(15) ildarovich, "изюминки" во второй половине задачи 3 я не увидел. - задача 5 на том-же запросе. Добавил в статью. Для меня такой подход, ну не сколько изюминка, возможно кислинка, но приятная :)
21. mr. Script (m..adm) 08.12.15 23:32

(18) ildarovich,
На всякий случай замечу, что в статье Расчет средних по периодам в запросе - это элементарно! показано, как рассчитать среднедневной остаток вообще БЕЗ расчета остатков по дням.
. Математика Вашего расчета сходится и оптимальна. Тогда поправлю себя "Но есть задачи как расчет среднесуточного остатка или оборачиваемости товара, в которых надо все даты.
22. mr. Script (m..adm) 09.12.15 00:06
(14) ildarovich,
По задаче 4:
Всего два свойства? - Но тогда все должно быть ГОРАЗДО проще!
Да, можно и проще. Первоначально делал запрос на разные количества свойств, а потом за отустствием времени плюнул, "обрубил" его и выложил как есть.
23. Александр Хомяк (logarifm) 09.12.15 01:06
У вас на СКЛ сработал паралелизм, необходимо отключать паралелиться запросы.
24. mr. Script (m..adm) 09.12.15 02:09
(23) logarifm, Да, это план выполнения запроса с поиском минимального значения при группировке. Этот процесс СКЛ разбил на несколько потоков. Почему необходимо отключать? Хоть это больше потребляет ресурсов в единицу времени, зато убыстряет выполнение задачи.
25. Сергей (ildarovich) 09.12.15 08:07
(19) m..adm, по вопросам 1-4 взаимопонимания мы не достигли, ну да ладно, я свое мнение высказал.
По вопросу 5 очень интересно. Такая информация (об эффективности в MS SQL ПО (...) В (ВЫБРАТЬ ... ИЗ)) здесь проскакивала, но без замеров и демонстрации плана запроса она не была так убедительна. Время на построение индекса в замерах учитывалось? - Проверю, буду иметь ввиду. Жаль только, что эффективность этого приема так сильно зависит от СУБД.
26. mr. Script (m..adm) 09.12.15 09:10
(25) ildarovich, нет. время, потраченное на создание индексов в тесте не учитывалось. Предполагалось, что на входе у нас уже есть индексированные таблицы .
27. Алексей (alest) 09.12.15 12:45
Поэтому я рекомендовал бы не делать сложных выборок-соединений с группировкой из виртуальных таблиц, а прочитать необходимые данные из виртуальной таблицы регистра во временную и далее их обрабатывать последующими пакетами запроса.

Смотрю результат оптимизации - то же соединение, группировка да еще и помещение во временную таблицу. Прирост скорости, скорее всего, получен был за счет замены таблицы Курсов на порождающий запрос. А в запросе так и осталось соединение Дней с виртуальной таблицей остаков/оборотов.
Прошу прощения, поспешил.
28. Иван Иванов (kosmo0) 10.12.15 09:02
Порой смотрю на тексты запросов и возникает мысль - страшно далеки они от народа практической реализации.

Почему
ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ВТ0.Ч + ВТ1.Ч*10 + ВТ2.Ч*100 + ВТ3.Ч*1000 КАК Число
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3
...Показать Скрыть


а не
ВЫБРАТЬ 0 КАК Ч ПОМЕСТИТЬ ВТ
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ  ВЫБРАТЬ 9;

ВЫБРАТЬ ВТ1.Ч + ВТ2.Ч*10 + ВТ3.Ч*100 + ВТ0.Ч*1000 КАК Число //изменен порядок ВТ0,ВТ1,ВТ2 и ВТ3
ИЗ ВТ КАК ВТ0,ВТ КАК ВТ1,ВТ КАК ВТ2,ВТ КАК ВТ3
...Показать Скрыть


Или потом сортировать результат теряя время полученное от всех предыдущих оптимизаций?
29. mr. Script (m..adm) 10.12.15 10:42
(28) kosmo0,
Порой смотрю на тексты запросов и возникает мысль - страшно далеки они от народа практической реализации.

1.В практической реализации сортировка необходима не только по датам, но и по другим разрезам выборки, поэтому все-равно придется сортировать или запросом, или на этапе компоновки результата. В практической реализации пакетных запросов с большим объемом данных важна индексация в первую очередь и правильное соединение запросов.
2. Изменив порядок таблиц в выражении, Вы можете однозначно утверждать, что в таком случае выборка будет всегда отсортирована? Результат получился таковым, потому что SQL сформировал такой план выполнения запроса. У Вас есть доводы?
3. Применение таких выборок - страховка от возможных потерь данных, в сравнении со случаями, когда периоды мы получаем из регистров. Что Вы там говорили о практике?
30. mr. Script (m..adm) 10.12.15 23:34
(13) ildarovich,
В этом запросе нет лишних действий, именно его и нужно тестировать для сравнения. Он сохраняет суть исходного "моего" запроса: для нахождения промежуточных остатков накапливаются обороты. Именно так и работает нахождение остатков платформой, если остатки требуется рассчитать внутри периода итогов.

Я не интересовался, как работает механизм нахождения остатков платформой. Если есть ссылка на описание, поделитесь.
Я планировал сделать сравнительные замеры своего запроса и запроса, который был предложен Вами выше в комментариях, да пока это невозможно, т.к. запросы выдают разные наборы данных. Предоставьте пожалуйста самый оптимальный с Вашей точки зрения запрос, который за любой период с отбором по складу даст выборку остатков номенклатуры на каждый день из периода. Я продолжу потом сравнительный анализ. В Вашей реализации запроса по некоторой номенклатуре не будет данных по остаткам на каждый день. Это вызвано тем, что для реализации алгоритма расчета Вы использовали периодичность "Период" таблицы "ОстаткиИОбороты". При такой реализации, если товар пришел первый раз на склад позже "НачалоПериода" - по этому товару будут отсутствовать данные по остаткам по дням от "НачалоПериода" до даты поступления этого товара.
31. Сергей (ildarovich) 11.12.15 10:54
(30) m..adm, (30) m..adm, информация как считаются остатки платформой внутри периода итогов есть в "белой книге". Это двухтомник "Профессиональная разработка в системе 1С:Предприятие".
Я специально проверил насчет
В Вашей реализации запроса по некоторой номенклатуре не будет данных по остаткам на каждый день. Это вызвано тем, что для реализации алгоритма расчета Вы использовали периодичность "Период" таблицы "ОстаткиИОбороты". При такой реализации, если товар пришел первый раз на склад позже "НачалоПериода" - по этому товару будут отсутствовать данные по остаткам по дням от "НачалоПериода" до даты поступления этого товара.
и ЧТОБЫ ЭТОГО НЕ БЫЛО использовал конструкцию
ВЫБРАТЬ
    &НачалоПериода КАК Период,
    Остатки.Номенклатура,
    Остатки.КоличествоНачальныйОстаток + 0 * Остатки.КоличествоПриход + 0 * Остатки.КоличествоРасход КАК Остаток
ПОМЕСТИТЬ ВТДвижения
ИЗ
    РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Период, , Склад = &Склад) КАК Остатки
...Показать Скрыть
где используется
+ 0 * Остатки.КоличествоПриход + 0 * Остатки.КоличествоРасход
которая должна давать нулевые записи, даже, если остатков на начало не было. А вы проверяли или заключение умозрительное?
32. mr. Script (m..adm) 11.12.15 12:08
(31) ildarovich,
которая должна давать нулевые записи, даже, если остатков на начало не было. А вы проверяли или заключение умозрительное?

Я действую по принципу "доверяй, но проверяй".Смотрите две ситуации с таблицей "Остатки и обороты" для такого стечения данных по движениям товара в отношении к нашему периоду выборки. В одном случае на конец периода есть остаток и таблица остатков-оборотов по периодичности "Период" дает данные. В другом случае - на конец периода нет остатка, таблица не дает данные при использовании периодичности "Период". Для второго случая результирующего запроса выпадают данные, до первого поступления товара. Первая дата в такой выборке будет - дата первого оборота из таблицы оборотов. Если бы использовалась периодичность остатков и оборотов "День", тогда мы получили бы данные, да логика Вашего общего запроса тогда не работала б. Поэтому я и написал, дайте окончательный правильный запрос.
Прикрепленные файлы:
ildarovich; +1 Ответить 2
33. Иван Иванов (kosmo0) 11.12.15 15:20
(29) Прежде всего хотелось бы адекватной реакции по сути, а не ответа в стиле -"мне адреналин с мочой в голову ударил и я стал контратаковать". (это видно по пункту 3 который добавлен до кучи и совершенно не относится к моему посту).

По пункту 1. В большинстве случаев желание получить список чисел или дат подряд означает что важно получение данных в разрезе дат. (но, опять же, это в реальной жизни).
По пункту 2. Вы можете ОДНОЗНАЧНО УТВЕРЖДАТЬ что верна Ваша точка зрения?

Я могу утверждать что описанный подзапрос был банально скопирован. Оптимизация запросов это желание привести к некому идеальному результату. Люди стремящиеся к идеалу не любят беспорядка. Результат же скопированного подзапроса это маленький бардак.

На этом откланяюсь, участвовать в говносраче не имею желания.
34. mr. Script (m..adm) 11.12.15 15:39
(33) kosmo0, 1. Вы залетели в эту тему с мыслью и заявлением
Порой смотрю на тексты запросов и возникает мысль - страшно далеки они от народа практической реализации.
. Я опровергну эту мысль тем, что подчеркнул: перестроенная Вашим образом выборка дала результат отсортированных чисел по возрастанию лишь потому, что сервер баз данных сформировал такой план выполнения запроса. Попросту говоря, вы подобрали запрос таким образом, чтобы результат бы отсортирован. Однако повторю то, что я хотел сказать. Ваша структура запроса не дает гарантии, что на другой версии сервера баз данных будет такой-же план выполнения запроса и Вы получите отсортированную таблицу. Логично?
2. Я также не могу утверждать, что на другой версии сервера базы данных, не получится упорядоченная таблица, т.к. это требует анализа, хорошего знания работы платформы сервера.
3. Мои выводы основаны на том, что в таком запросе 1С с сочетанием таблиц не прослеживается явное создание сортировки. Если бы Вы построили эту выборку на базе "Левых" соединений, возможно я бы согласился.
4. И последнее. Не я заявлял "далеко от практики" без особых аргументов. Я говорю и анализирую. В случае моей ошибки, я поправляю себя. Вы можете заметить перечеркнутые выражениях в моих постах. Посему, г...срач, как Вы говорите, скорее всего развожу не я.
Спасибо за Ваше участие.
35. mr. Script (m..adm) 12.12.15 12:44
(14) ildarovich,
По задаче 4:
Всего два свойства? - Но тогда все должно быть ГОРАЗДО проще!
Все комбинации получается сразу всего одним простым запросом

Запрос по задаче 4 у меня был сложным и в несколько пакетов, т.к. разрабатывался как универсальный запрос на произвольное количество свойств и в последствии был "обрублен" и выложен как есть. Исправил этот недоработанный момент и изменил 4-й раздел статьи. В разделе я выложил новый запрос, который без дополнительных временных таблиц выдаст выборку "в столбик" отсортированных и пронумерованных комбинаций сочетаний свойств товара. Как Вам это? ГОРАЗДО проще или нет?
36. mr. Script (m..adm) 12.12.15 13:07
Обработку для тестирования запросов по 5-му разделу статьи прилагаю тут, т.к. она идет как приложение к статье, а не программный продукт. При запуске не стоит сразу указывать много временных таблиц для анализа и большие размеры таблиц, т.к. выполнение может быть продолжительным, особенно, на файловом варианте. Ссылка на обработку: http://www.ex.ua/691114295869
37. Сергей (ildarovich) 12.12.15 15:02
(35) m..adm, запрос по разделу 4 я посмотрел. Про "зеркально" понял. Предыдущего варианта у меня нет, поэтому насколько удалось упрощение сказать не могу. Мог бы подумать, как упростить нумерацию в вашей схеме, но большого желания нет. Написав ту исходную статью, не увидел большого интереса к этой задаче. Хотя она взята из практики. Те, кто въехал, делают то же самое через декартово соединение таблиц свойств. Нумерацию чаще удобнее делать вне запроса. Поэтому задача довольно экзотическая и тратить на нее время жалко.
Но у меня встречный вопрос: а зачем вам свое решение в этой задаче. Ведь в исходной статье решение исчерпывающее и универсальное (на ЛЮБОЕ количество свойств). С быстродействием проблем нет. Свойства два - тогда хватит одного повтора и длина запроса будет меньше или равна длине вашего варианта (вы немного схитрили и записали в одну строку несколько полей). Если раскрыть запросы конструктором, то длина будет почти одинаковой. А в комментарии я показал ну очень простую и понятную схему для двух свойств без всякого накопления. Зачем вам топтаться на этой экзотической и уже решенной задаче? Какую новизну, какую идею вы хотели привнести в решение?
(32) смоделированная вами ситуация выглядит надуманной. В варианте (13) выпадают только строки, которые имеют нулевые начальные И конечные остатки И приход в середине интервала И который весь закрывается возвратом (приходом с минусом). Редкая ситуация. Можно было бы пренебречь. Ведь мы пренебрегаем случаями, когда приход и расход делается в один день (гардероб, детский сад). Но в принципе я не возражаю доработать запрос на отмеченный в (32) случай. Сделаю это чуть позже. Заранее могу сказать, что результаты теста будут зависеть от данных базы. Поэтому для честного соревнования нужно будет договорится о том, на каких данных будет идти тестирование. Кроме того, я знаю еще минимум три-четыре других способа интерполяции остатков. Их пока не рассматриваем?
38. mr. Script (m..adm) 12.12.15 22:54
(37) ildarovich, По 4 разделу.
Но у меня встречный вопрос: а зачем вам свое решение в этой задаче. Ведь в исходной статье решение исчерпывающее и универсальное (на ЛЮБОЕ количество свойств)
Первоначально я хотел сделать универсальный пакетный запрос на любое количество видов свойств, в котором не требовалось бы делать умножение таблиц взависимости от количества видов свойств. На этой реализации я заштопорился и чтобы не тратить уйму времени, выложил частичную реализацию - запрос на 2 вида свойств, с любым количеством значений свойств. Предыдущий запрос был интересен тем, что надо было немного поднапрячь воображение для разбора его алгоритма работы. Ваше заявление "можно ГОРАЗДО проще"я принял как вызов и вот Вы видите запрос БЕЗ временных таблиц, который делает комбинации любого набора значений свойств в разрезе товара но с ограничением: в пределах одного товара должно быть только 2 вида свойств. Запрос написан компактнее для удобства понимания. Если реализовать идентичный механизм на базе Ваших запросов в статье http://infostart.ru/public/295343/ то он будет не такой компактный. Я донес Вам свою мысль?

(32) смоделированная вами ситуация выглядит надуманной. В варианте (13) выпадают только строки, которые имеют нулевые начальные И конечные остатки И приход в середине интервала И который весь закрывается возвратом (приходом с минусом). Редкая ситуация. Можно было бы пренебречь. Ведь мы пренебрегаем случаями, когда приход и расход делается в один день (гардероб, детский сад). Но в принципе я не возражаю доработать запрос на отмеченный в (32) случай. Сделаю это чуть позже
Да, сделайте, я сравню потом производительность запросов. "Пренебречь" исключительными ситуациями и рядом данных во многих расчетах можно. Когда же речь идет о создании четкого алгоритма, то никто ничем не пренебрегает! В этом я категорически не соглашусь. В моей реализации запроса, день, который закрывается с нулевым оборотом будет отмечен с нулевым остатком и не выпадет из выборки как у Вас.

В заключение хочу подвести некий итог.
Я потратил достаточно времени на статью, чтобы поделиться одним из интересных моментов реализации выборки данных при получении остатков и срезов.
Я не утверждаю, что это единственный и тем-более правильный для каждого случая вариант реализации. Из моего опыта, на громадных объема данных, множеством временных таблиц и запросах в тысячи строк такой подход хорошо экономит время тем самым, увеличивают быстродействие системы.
Рациональное зерно в статье есть, однако что я вижу. Я открываю свою статью и вижу "Лучший комментарий" от Вас, в котором человек с огромной репутацией на этом ресурсе и опытом, косвенно говорит, что статья ни-о-чем. Этот комментарий сразу же поддерживает не глядя несколько человек. В итоге, читатель смотрит мельком статью, смотрит лучший комментарий, понимает "статья ни-о-чем" и уходит. Такой исход меня крайне не устраивает.
Посему, предлагаю как-то исправить эту неудобную ситуацию.

Далее Ваше внимание переключу на тему http://infostart.ru/public/421101/. В ней Вы тоже поспешили прокомментировать мою реализацию и выбились в "лучшие комментарии". В ней я выложил готовое решение под конкурс http://forum.infostart.ru/forum1/topic78895/ и получил за это вознаграждение. В конкурсе не шла речь о минимализме. Я сомневаюсь и готов поспорить, о компактности реализации задачи "Найти кратчайший путь коня между двумя заданными полями в теме http://infostart.ru/public/306536/. Посему, продолжу при наличии времени там.

Спасибо.

39. Сан Саныч (herfis) 14.12.15 12:06
(38) Статьи ildarovich'а предельно лаконичны, поучительны и содержательны. За что ему большой респект. Непросто писать просто о сложном.
В вашей статье, по сути, первичен и интересен только один момент (лично для меня, конечно же) - способ оптимизации производительности запросов 1С в MSSQL в некоторых шаблонных ситуациях, путем использования коррелирующего подзапроса. Но это эта информация подана значительно более громоздко, чем могла бы. Отдельная статья с таким исследованием (а если бы еще и в сравнении с другими СУБД - вообще бомба) смотрелась бы гораздо более интересно и была бы более эффективна для аудитории, по моему мнению. Намеки на заангажированность ildarovich'а, которая якобы встает стеной между вами и аудиторией, мешая ей адекватно потреблять инновационный контент - несостоятельны и вызывают улыбку.
Но мне понятно ваше негодование как автора и творца, который потратил время и силы, а в ответ получил неблагодарную публику. Да как они смеют, вообще!
ildarovich; +1 Ответить 1
40. mr. Script (m..adm) 14.12.15 14:50
(39) herfis,
Статьи ildarovich'а предельно лаконичны, поучительны и содержательны

Да, согласен с Вами. Товарищ ildarovich молодец.
..подана значительно более громоздко, чем могла бы
тоже согласен, потому что привык все разжевывать. Тем более, я применил подход этот в нескольких запросах.
Публика-то разная. Кому-то надо разжевывать, а кто-то и на пальцах поймет.
Да как они смеют, вообще!
- 100%, Вы мои мысли прочли! :) Прямо и добавить нечего.
Но добавлю. Во всем надо сомневаться и учиться мыслить самому, а не только "как в книжке написано или кем-то сказано".
Спасибо за веселый комментарий.

Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа