Что быстрее работает - ГДЕ или соединение? #653634


#0 by suvolod
Пусть есть две таблицы: 1-я содержит поле номенклатура, период. 2-я содержит поля номенклатура, цена, период. мне нужно соединить их в одну таблицу по полям Номенклатура + Период, однако вторая таблица строиться на основе ФИЗИЧЕСКОЙ таблицы ЦеныНоменклатуры, и должна содержать только записи по одному типу цен. Возник вопрос: как правильней отфильтровать записи по регистру цен? 1-й способ: это просто применить условие ...ГДЕ при выборке данных второй таблицы. Т.е., как я понимаю - сперва будут выбраны все записи по Регистру цен, после чего записи по ненужному типу цен будут отброшены. 2-й способ: в 1-ю таблицу добавить поле &ТипЦен и соединить обе таблица уже по трем полям: Номенклатура+Период+ТипЦен. Дело в том, что я не совсем понимаю, как будет происходить выборка данных в этом случае.. может, она будет быстрее и не потребует чтения всей таблицы цен?
#1 by suvolod
на всякий случай: такая задача оптимизации возникла при необходимости решения учетной задачки способом "срез последних на каждую дату"
#2 by GANR
запросы в ветку
#3 by suvolod
Пока сделал так (задача) - выбрать поступления товаров за заданный период + прицепить к ним колонку розничных цен:    ПартииТоваровНаСкладах.Регистратор.Контрагент КАК Поставщик, ГДЕ    ПартииТоваровНаСкладах.Период МЕЖДУ &Дата1 И &Дата2    И ПартииТоваровНаСкладах.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)    И ПартииТоваровНаСкладах.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг СГРУППИРОВАТЬ ПО    ПартииТоваровНаСкладах.Регистратор,    ВложенныйЗапросПартииСПериодом.Стоимость,
#4 by МихаилМ
одинаково для субд используюмых 1с
#5 by H A D G E H O G s
Пофиг. Главное, ты выбрал первым запросом нужное из Партий, этого достаточно. А то я уж сразу возбудился, как увидел Вложенный и Партии в нем. Но потом присмотрелся.
#6 by suvolod
уже что-то.. спасибо. Тогда наверное буду все-таки соедиенением таблиц, т.к. в противном случае придется выборку цен делать вложенным запросом (иначе если я вставлю условие ГДЕ В результирующий запрос, у меня отсеются строки, по которым никогда не было розничных цен)
#7 by suvolod
заодно задам еще один вопрос: в классическом примере решения задачи "срез последних на каждую дату" предлагается дважды обращаться к физической таблице регистра цен - сначала по условию выбора максимального периода из минимально возможного периода ВЫБРАТЬ Затем по условию равенства периода И ВложенныйЗапросПартииСПериодом.ТипЦен = ЦеныНоменклатуры.ТипЦен А разве не правильнее/быстрее было-бы не дважды делать выборку данных из физической таблицы регистра цен, а сперва сделать срез последних на начало выбираемых данных, + через объединение добавить новые записи за весь выбираемый отчетом период.
#8 by suvolod
... чуть подробнее что я предполагаю: 1. Делаю срез последних - сразу с отбором в параметрах вирт. таблицы по номенклатуре, типу цен. 2. Делаю выборку данных из физ. таблицы регистра по записям, которые были добавлены за период [Дата1, Дата2] - с фильтацией неподходящих записей по ГДЕ 3. Объединяю эти две таблицы и затем уже от полученной результирующей таблице ищу максимум по условию
#9 by МихаилМ
для 1с 8.2 все равно fullcscan. для 8.3 - хратинся таблица срезов как остатки. почитайте про декларативность запросов.
#10 by suvolod
. Получается, СрезПоследних в 8.2 все равно неявно прочитает всю таблицу цен. Я правильно понял?
#11 by МихаилМ
нет. я неправильно написал. может  задействоваться индекс. извиняюсь.
#12 by МихаилМ
+ но индекс будет сканироваться
#13 by suvolod
Спасибо, а покритикуйте тогда еще один доп. способ оптимизации: прочитать всю таблицу цен, выбрать из нее поля Номенклатура, Цена, Период, поместить во ВремТаб, проиндексировать поля Номенклатура + Период, сразу сделать отбор по ГДЕ на нужный тип цен и номенклатуру. И затем в "классическом" способе решения задачи использовать уже эту частично отфильтрованную таблицу - вместо повторного способа чтения всей физ. таблиц.
#14 by suvolod
.. куча опечаток в конце. Читайте как "- вместо повторного чтения всей физической таблицы цен"
#15 by МихаилМ
что такое предположить конечно можно. но будте конкретней.
#16 by МихаилМ
+ этот форум будут читать малосведущие. не ленитесь приводить ссылки на "КЛАССИЧЕСКИЕ" для ВАС  понятия.
#17 by suvolod
прошу прощения,  описан здесь: . Называется "способ непосредственно в запросе"
#18 by suvolod
как предварительные выводы: если я цены выберу как СрезПоследних на ДатаНач + добью их новыми записями с ДатаНач по ДатаКон, проиндексирую результат, помещу во ВремТаб, и далее буду работать с этой таблицей вместо повторного чтения физической - как минимум медленнее запрос от этого не станет?
#19 by suvolod
Как окончательные выводы: тестировал на рабочей базе с разными периодами выборки данных. "Классический" запрос всегда отрабатывает быстрее ~ 20-30%. Получается, мое предположение из - неверное. Причем обнаружил странную закономерность: мой запрос из , построенный по классическому варианту, отрабатывает быстрее, если в запросе убрать индексирование по полям Номенклатура + Период.
#20 by Fragster
а сколько у тебя строк во временной таблице?
#21 by suvolod
. Запрос из , оказывается, я приводил как раз без индексирования этих полей. Чтобы было понятнее - о чем говорю - я тестировал запрос с индексированием полей во времтаб, т.е. начало этого запроса было такое: ВЫБРАТЬ    ПартииТоваровНаСкладах.Регистратор.Контрагент КАК Поставщик, ГДЕ    ПартииТоваровНаСкладах.Период МЕЖДУ &Дата1 И &Дата2    И ПартииТоваровНаСкладах.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)    И ПартииТоваровНаСкладах.Регистратор ССЫЛКА Документ.ПоступлениеТоваровУслуг СГРУППИРОВАТЬ ПО    ПартииТоваровНаСкладах.Регистратор, ;
#22 by suvolod
Примерно 30.000
#23 by H A D G E H O G s
Где ты видел путь назад? Очнись, нам уже не вернуться! Заменить ПартииТоваровНаСкладах.Регистратор.Контрагент КАК Поставщик, на ВЫРАЗИТЬ(ПартииТоваровНаСкладах.Регистратор как Документ.ПоступлениеТоваровУслуг).Контрагент КАК Поставщик,
#24 by фобка
всё не читал, "где" быстрее чем "джоин"
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С