Имя: Пароль:
1C
1С v8
Запрос очень долго отрабатывается, подскажите оптимизацию, если она есть
,
0 vse_serjezno
 
30.04.14
15:54
Здравствуйте!
Мне нужно определить количество отгрузок за период по индексам места доставки(т.е. индексу адреса клиента).

Запрос у меня такой:

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

СГРУППИРОВАТЬ ПО
    ВЫРАЗИТЬ(ПартнерыКонтактнаяИнформация.Представление КАК СТРОКА(6))



Он отрабатывает верно. Но Ооочень долго! Все таки поле Представление имеет строковый тип данных, еще и длина 500. И чем больше период обработки, тем дольше, а мне за год надо его формировать.

Есть ли способы его оптимизировать?
1 Wobland
 
30.04.14
15:55
>И ВЫРАЗИТЬ(ПартнерыКонтактнаяИнформация.Представление КАК СТРОКА(6)) В (&Представление)
что это?
2 vse_serjezno
 
30.04.14
15:56
(1) &Представление это список индексов, которые мне нужны.
3 vse_serjezno
 
30.04.14
15:56
Т.е. выбирать колво заказов по тем индексам, которые передаются в списке.
4 Wobland
 
30.04.14
15:57
тоесть, пока нет мысли, что это - какое-то изощрение?
5 vse_serjezno
 
30.04.14
15:59
(4) Я передаю список индексов в запрос. Мне нужно КоличествоЗаказов по тем пунктам доставки, индексы которых я передаю.
6 vse_serjezno
 
30.04.14
16:00
То же самое:

И ВЫРАЗИТЬ(ПартнерыКонтактнаяИнформация.Представление КАК СТРОКА(6)) В (&СписокИндексов)
7 Rovan
 
гуру
30.04.14
16:01
(0) обязательно до 6 символов сжимать ??
8 ptiz
 
30.04.14
16:03
1. Сделать ВТ только по контактной информации
2. Сделать ВТ только по данным из РегистрНакопления.РасчетыСКлиентами с фильтром по клиентам из п.1, причем быстрее будет - по физ. таблице, а не виртуальной.
3. Соединить п.1 и п.2
9 vse_serjezno
 
30.04.14
16:03
Представление содержит полностью строку адреса. Я вот этим:
ВЫРАЗИТЬ(ПартнерыКонтактнаяИнформация.Представление КАК СТРОКА(6)), - выбираю первые 6 символов( то есть индекс ),
и вот этим:
В (&СписокИндексов), - обозначаю, что мне нужны только те, что у меня в списке.
10 Жан Пердежон
 
30.04.14
16:04
Попоробуй в ВТ партнеров сначала засунуть
11 Жан Пердежон
 
30.04.14
16:05
так же есть подозрение, что не тот регистр используешь
12 Ёпрст
 
30.04.14
16:11
(0) используй, для начала, КонтактнаяИнформация.Поле1, ибо это и есть индекс, если по кладру забивали
13 Ёпрст
 
30.04.14
16:20
Ну и так, хотя бы..

ВЫБРАТЬ
    КонтактнаяИнформация.Объект КАК Объект
    КонтактнаяИнформация.Поле1 КАК Индекс
ПОМЕСТИТЬ Табличка
ИЗ РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
ГДЕ
    КонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Адрес)
    И КонтактнаяИнформация.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АдресТорговойТочки)
И КонтактнаяИнформация.Поле1 в (&СписокИндексов)
;
ВЫБРАТЬ
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ РасчетыСКлиентамиОбороты.Регистратор) КАК КоличествоЗаказов,
    Табличка.Индекс КАК Индекс
ИЗ
   РегистрНакопления.РасчетыСКлиентами.Обороты(&НачалоПериода, &ОкончаниеПериода, Авто, ) КАК РасчетыСКлиентамиОбороты
        ПО Табличка.Объект = РасчетыСКлиентамиОбороты.ЗаказКлиента.Партнер
ГДЕ
    РасчетыСКлиентамиОбороты.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
    И РасчетыСКлиентамиОбороты.ЗаказКлиента ССЫЛКА Документ.ЗаказКлиента
СГРУППИРОВАТЬ ПО
    Табличка.Индекс
14 Ёпрст
 
30.04.14
16:20
Только, вот такое соединение
ПО Табличка.Объект = РасчетыСКлиентамиОбороты.ЗаказКлиента.Партнер

не комильфо, если че..
15 Ёпрст
 
30.04.14
16:21
ну и там.. иннер джоин воткни (забыл я при копипасте)
16 vse_serjezno
 
30.04.14
16:24
(11) почему?
17 Rovan
 
гуру
30.04.14
16:27
(0) конфа какая это ?
18 vse_serjezno
 
30.04.14
16:28
(13) У меня нет РС КОнтактнаяИнформация. УТ11
19 Ёпрст
 
30.04.14
16:29
(18) ну, воткни тот, что есть (ут11 не видел)
20 vse_serjezno
 
30.04.14
16:31
у меня нет отдельно индекса, к сожалению. ПОэтому всю строку Представление потрошу.
21 Rovan
 
гуру
30.04.14
16:32
(+17) если УТ10, то в РС КонтактнаяИнформация
есть и другие поля !!
ищи индекс почтовый в поле "Поле1"
22 vse_serjezno
 
30.04.14
16:32
(21) УТ 11.
23 vvp91
 
30.04.14
16:33
>> (0) ... Но Ооочень долго! ... оптимизировать?

1. Очевидно, что это УТ 11.
2. Почему адрес доставки определяется из партнера, а не из реализации?
3. Зачем выбирается количество заказов, когда заказ может быть один, а реализаций несколько?
4. Причем тут регистр расчетов с клиентами с отборами по реализациям, когда отгрузка может быть на комиссию, и тогда расчеты не дадут нужных данных?
5. Причем тут заказы, когда отгрузка (реализация) может быть без заказа?
6. Регистр расчетов с клиентами содержит по 2 записи на реализацию, это будет давать ложные данные в ряде случаев.

Теперь технических проблемах регистра:
1. Главная проблема - разыменование составного поля в соединении (ПартнерыКонтактнаяИнформация.Ссылка = РасчетыСКлиентамиОбороты.ЗаказКлиента.Партнер).
2. Получение оборотов по АВТО (Обороты(&НачалоПериода, &ОкончаниеПериода, Авто, )) для доступа к регистраторам.

На фоне этих проблем, проблемы с отбором партнеров по первым 6-ти символам в представлении таб.части контактной информации просто НЕ существует, причем даже использование ВЫРАЗИТЬ вместо ПОДСТРОКА не сильно ухудшает ситуацию.


Технически правильно получить индексы партнеров можно так:

ВЫБРАТЬ
    Адреса.Ссылка КАК Партнер,
    ПОДСТРОКА(Адреса.Представление, 1, 6) КАК Индекс
ПОМЕСТИТЬ
    Адреса
ИЗ
    Справочник.Партнеры.КонтактнаяИнформация КАК Адреса
ГДЕ
    Адреса.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Адрес)
    И Адреса.Вид = &ВидАдреса
ИНДЕКСИРОВАТЬ ПО
    ПОДСТРОКА(Адреса.Представление, 1, 6)
;


Самое простое - это просто выбрать реализации за период

ВЫБРАТЬ
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Отгрузки.Ссылка) КАК ВсегоОтгрузок,
    Адреса.Индекс
ИЗ
    Документ.РеализацияТоваровУслуг КАК Отгрузки
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Адреса
        ПО Адреса.Партнер = Отгрузки.Партнер
ГДЕ
    Отгрузки.Дата МЕЖДУ &НачалоПериода И &ОкончаниеПериода
    И Отгрузки.Проведен
    И Адреса.Индекс В (&Индексы)
СГРУППИРОВАТЬ ПО
    Адреса.Индекс
24 Rovan
 
гуру
30.04.14
16:34
еще попробуй вместо
ВЫРАЗИТЬ(ПартнерыКонтактнаяИнформация.Представление КАК СТРОКА(6))
вот так
ПОДСТРОКА(ПартнерыКонтактнаяИнформация.Представление,1,6)
25 vse_serjezno
 
30.04.14
16:40
(23) Спасибо.
Я переварю информацию, исправлю запрос. И вернусь с новыми вопросами или благодарностями.)
26 Ёпрст
 
30.04.14
16:45
(23) только условие на индекс нужно пихать в первый запрос
27 vvp91
 
30.04.14
17:06
(26) только условие на индекс нужно пихать в первый запрос
С чего ты взял, что это будет оптимальнее? Замеры делал?

Представление в контактах партнера НЕ индексировано, соответственно будет полный перебор таблицы для отбора данных. А это уже повод, чтобы сбросить нужные данные во временную таблицу средствами СУБД и потом уже использовать ВТ.

И, оказывается, что временем записи ВТ из 2 полей даже по сотням тысяч записей можно пренебречь. Тогда как неиндексированый отбор по подстроке оказывается для СУБД не такой дешевой операцией.

На деле, разницы в том, где отбирать индексы - при формировании ВТ или при фильтрации в основном запросе - практически не будет.
28 Ёпрст
 
05.05.14
09:26
(27) делал, будет быстрее
29 НЕА123
 
05.05.14
09:30
(0)
может убрать "ГДЕ"? засунуть все в "ПО".
30 MrStomak
 
05.05.14
10:16
(27) Ну ты жж0шь, пренебречь временем создания ВТ с 100000 записей, пренебречь временем на создание индекса в ВТ по нафиг не нужным записям и мотивировать что "неиндексированный отбор - тяжелая операция"... =) Раз таблица не индексирована по нужному нам полю, то мы её скопируем, проиндексируем и потом отберём по нужному полю...))) Это похоже на какой-то армейский юмор!
31 Chai Nic
 
05.05.14
10:18
Главные тормоза - из-за соединения с виртуальной таблицей. Соединять можно только с реальной таблицей (из базы или временной). Соединения с виртуальной таблицей - по сути, соединение с подзапросом.. А соединения с подзапросами часто тормозят из-за отсутствия статистики для выбора оптимального плана запроса.
32 Полотенчик
 
05.05.14
10:32
(0) Отборы по второй таблице засунь не в ГДЕ, а в ПО чтобы сначала в ней сделался отбор и только потом она соединялась с основной таблицей

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

Или использовать временные и потом соединять их
Есть два вида языков, одни постоянно ругают, а вторыми никто не пользуется.