Имя: Пароль:
1C
1С v8
как оптимизировать запрос
,
0 svchernova
 
16.06.15
13:42
Всем добрый день!
Написала простой запрос, у меня в файловой среде работает очень быстро, а у заказчика на sql работает очень медленно.
В запросе использую регистры бухгалтерии, остатки и обороты, при этом  таблицы остатков и оборотов стоят в запросе на одном уровне. Остатки по счету выбираются мгновенно, а обороты медленнее, та как баз большая. Правильнее ли сделать вложенный запрос, и что нужно поместить во вложенный - остатки или обороты?
Спасибо!
1 Мимохожий Однако
 
16.06.15
13:49
ОФФ: Телепаты АУ!
2 leonidkorolev
 
16.06.15
13:49
Запрос выложите сюда
3 svchernova
 
16.06.15
13:51
минутку, пожалуйста.. сейчас..
4 svchernova
 
16.06.15
13:55
Вот..


Запрос.Текст = "ВЫБРАТЬ
               |    ТиповойОстатки.Счет КАК Счет,
               |    ТиповойОстатки.Субконто1 КАК Контрагент,
               |    ТиповойОстатки.Субконто1.КБЕ КАК КБЕ,
               |    ТиповойОстатки.Субконто1.ИдентификационныйКодЛичности КАК ИИН,
               |    ТиповойОстатки.Субконто2 КАК ДоговорКонтрагента,
               |    ТиповойОстатки.Субконто3 КАК ВидСтрахования,
               |    ТиповойОстатки.Организация КАК Организация,
               |    ТиповойОстатки.СуммаОстаток КАК СуммаОстаток,
               |    ТиповойОстатки.Субконто2.ДатаДоговора КАК ДатаДоговора,
               |    ТиповойОстатки.Субконто2.ДатаНачалаДействияДоговора КАК ДатаНачала,
               |    ТиповойОстатки.Субконто2.ДатаОкончанияДействияДоговора КАК ДатаОкончания,
               |    0 КАК СтраховаяПремия,
               |    Оплата.СуммаОплаты,
               |    Оплата.ДатаОплаты,
               |    ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяССылка) КАК Посредник,
               |    0 КАК ПризнакДопДата
               |ИЗ
               |    РегистрБухгалтерии.Типовой.Остатки(&ДатаКон, Счет = &С128041, , Организация В (&СписокОрганизаций)) КАК ТиповойОстатки
               |        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
               |            ТиповойОбороты.Организация КАК Организация,
               |            ТиповойОбороты.КорСубконто1 КАК Контрагент,
               |            ТиповойОбороты.КорСубконто2 КАК ДоговорКонтрагента,
               |            ТиповойОбороты.КорСубконто3 КАК ВидСтрахования,
               |            СУММА(ТиповойОбороты.СуммаОборот) КАК СуммаОплаты,
               |            МАКСИМУМ(ТиповойОбороты.Период) КАК ДатаОплаты
               |        ИЗ
               |            РегистрБухгалтерии.Типовой.Обороты(, &ДатаКон, Запись, Счет В (&СчетаОплаты), , Организация В (&СписокОрганизаций), КорСчет В (&КорСчет), ) КАК ТиповойОбороты
               |        
               |        СГРУППИРОВАТЬ ПО
               |            ТиповойОбороты.Организация,
               |            ТиповойОбороты.КорСубконто1,
               |            ТиповойОбороты.КорСубконто3,
               |            ТиповойОбороты.КорСубконто2) КАК Оплата
               |        ПО ТиповойОстатки.Организация = Оплата.Организация
               |            И ТиповойОстатки.Субконто1 = Оплата.Контрагент
               |            И ТиповойОстатки.Субконто2 = Оплата.ДоговорКонтрагента
               |            И ТиповойОстатки.Субконто3 = Оплата.ВидСтрахования
               |
               |УПОРЯДОЧИТЬ ПО
               |    Организация,
               |    Контрагент,
               |    ДоговорКонтрагента,
               |    ВидСтрахования,
               |    ДатаНачала УБЫВ
5 ДенисЧ
 
16.06.15
13:56
Я бы выложил обе таблицы во временные, потом соединял.
6 svchernova
 
16.06.15
13:56
я немного его упростила, убрала таблицы, которые сейчас несущественны
7 svchernova
 
16.06.15
13:57
(5) почему? я вот и хочу понять, как грамотно нужно составить запрос
8 ДенисЧ
 
16.06.15
13:58
(7) Если хочешь понять, сначала прочитай рекомендации 1с на ИТС по поводу оптимизации запросов.
В частности, она там сильно не рекомендует делать соединения с виртуальными таблицами
9 lxndr
 
16.06.15
14:00
+
1.
ТиповойОстатки.Субконто1.*
ТиповойОстатки.Субконто2.* - убрать, разыменовать вручную

2.
Нормализовать виды субконто
10 lxndr
 
16.06.15
14:01
и вообще странненький запрос. Ведомость по взаиморасчетам? Тогда остатки и обороты по счетам расчетов, не?
11 el7cartel
 
16.06.15
14:01
(7) 1.1 При написании запросов не следует использовать соединения с вложенными запросами. Следует соединять друг с другом только объекты метаданных или временные таблицы. Если запрос использует соединения с вложенными запросами, то его следует переписать с использованием временных таблиц (не важно с какой стороны соединения находится вложенный запрос).

Если запрос содержит соединения с вложенными запросами, то это может привести к следующим негативным последствиям:

Крайне медленное выполнение запроса при слабой загрузке серверного оборудования. Замедление запроса может быть очень значительным (до нескольких порядков).
Нестабильная работа запроса. При некоторых условиях запрос может работать достаточно быстро, при других - очень медленно.
Значительная разница по времени выполнения запроса на разных СУБД.
Повышенная чувствительность запроса к актуальности и полноте статистик. Сразу после полного обновления статистик запрос может работать быстро, но через некоторое время опять замедлиться.
12 МихаилМ
 
16.06.15
14:03
выбирайте сразу ОстаткиИОбороты
13 svchernova
 
16.06.15
14:03
(7) я почитала кое-что, перед тем как сюда писать. Бурмистров рекомендует использовать временные ТЗ в запросе, как параметры.. или я тебя не поняла
14 МихаилМ
 
16.06.15
14:04
+(12)
либо распаралльте
с помощью UNION
15 Мимохожий Однако
 
16.06.15
14:05
Сделай замер всех вариантов и сразу поймёшь, что лучше.
16 Зеленый пень
 
16.06.15
14:06
Делаем пакетный запрос
1: Выбираем остатки, помещаем во временную таблицу ТиповойОстатки
2: Выбираем обороты, в условии виртуальной таблицы используем условие: КорСубконто1 В (ВЫБРАТЬ ТиповойОстатки.Субконто1 ИЗ ТиповойОстатки)
3: Соединяем
17 Dmitrii
 
гуру
16.06.15
14:08
(13) > Бурмистров рекомендует использовать временные ТЗ в запросе, как параметры.. или я тебя не поняла

Правильно рекомендует. Но ты не поняла и не используешь в своем запросе эту рекомендацию.
18 Лефмихалыч
 
16.06.15
14:09
Данных в файловой нет ни хрена, вот он и работает быстро.

1. Отборы по видам субконто надо использовать обязательно.
2. Поля составного типа надо ВЫРАЗИТЬ, а при обращении к их реквизитам обязательно надо выразить
3. соединение с вложенным запросом убрать, чтобы не было
4. Есть таблица ОстаткиИОбороты, используйте ее
5. Обращение к оборотам без начальной даты с детализацией до записи в любом случае быстро работать на продуктивных базах не будет
19 Dmitrii
 
гуру
16.06.15
14:09
Вот это безобразие:

ТиповойОстатки.Субконто1.КБЕ КАК КБЕ

Заменить на что-то вроде:

ВЫРАЗИТЬ(ТиповойОстатки.Субконто1 КАК СправочникюКонтрагенты).КБЕ КАК КБЕ
20 Dmitrii
 
гуру
16.06.15
14:12
(18) > Есть таблица ОстаткиИОбороты, используйте ее

Спорное утверждение. Остатки нужны по одним счетам, а обороты  она берет по другим.
21 svchernova
 
16.06.15
14:12
(17) Даб я не использовала его рекомендацию, я это понимаю. То есть правильнее будет, как говорит Зеленый Пень (16) Выбрать остатки,  поместить их в ТЗ и использовать эту ТЗ в запросе как параметр?
22 svchernova
 
16.06.15
14:13
(19), (20) Да, счета разные
23 Drac0
 
16.06.15
14:14
(21) Не ТЗ, а ВТ. Временная таблица зарос.

ВЫБРАТЬ
               |    ТиповойОстатки.Счет КАК Счет,
               |    ТиповойОстатки.Субконто1 КАК Контрагент,
               |    ТиповойОстатки.Субконто1.КБЕ КАК КБЕ,
               |    ТиповойОстатки.Субконто1.ИдентификационныйКодЛичности КАК ИИН,
               |    ТиповойОстатки.Субконто2 КАК ДоговорКонтрагента,
               |    ТиповойОстатки.Субконто3 КАК ВидСтрахования,
               |    ТиповойОстатки.Организация КАК Организация,
               |    ТиповойОстатки.СуммаОстаток КАК СуммаОстаток,
               |    ТиповойОстатки.Субконто2.ДатаДоговора КАК ДатаДоговора,
               |    ТиповойОстатки.Субконто2.ДатаНачалаДействияДоговора КАК ДатаНачала,
               |    ТиповойОстатки.Субконто2.ДатаОкончанияДействияДоговора КАК ДатаОкончания,
               |    0 КАК СтраховаяПремия,
               |    Оплата.СуммаОплаты,
               |    Оплата.ДатаОплаты,
               |    ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяССылка) КАК Посредник,
               |    0 КАК ПризнакДопДата
               (!!)|ПОМЕСТИТЬ ВТ_Остатки (!!)
               |ИЗ
               |    РегистрБухгалтерии.Типовой.Остатки(&ДатаКон, Счет = &С128041, , Организация В (&СписокОрганизаций)) КАК ТиповойОстатки
24 svchernova
 
16.06.15
14:14
(14) Ты имеешь ввиду "Объединить все"?
25 Drac0
 
16.06.15
14:15
+(23) Потом в этом же (!) запросе мжно обращаться к ВТ_Остатки
26 Dmitrii
 
гуру
16.06.15
14:15
(21) Да. ИМХО, это было бы самым правильным.
Только уточню (16): можно в параметрах попробовать не по одному субконто, а сразу по всем:
(КорСубконто1, КорСубконто2, КорСубконто3) В (ВЫБРАТЬ ТиповойОстатки.Субконто1, ТиповойОстатки.Субконто2, ТиповойОстатки.Субконто3 ИЗ ТиповойОстатки)
27 svchernova
 
16.06.15
14:15
(25) а, поняла.. Это даст эффект?
28 Drac0
 
16.06.15
14:17
(27) Чаще всего дает. Это позволяет избежать соединения виртуальных таблиц, которое приводит оптимизатор SQL в дикий ступор. Как минимум это надо пробовать.
29 svchernova
 
16.06.15
14:18
(26)(28) Тут рекомендации использовать ТЗ в запросе или ВТ, что правильнее?
30 Dmitrii
 
гуру
16.06.15
14:19
(27) Не забудь использовать ВЫРАЗИТЬ! см. (19), (18)п.2, (9)
31 asady
 
16.06.15
14:19
зачем периодичность "запись"?
32 svchernova
 
16.06.15
14:20
(30) ага, не забуду
33 Dmitrii
 
гуру
16.06.15
14:20
(29) Временную правильнее. Нафига выгружать результат запроса в ТЗ, а потом пихать ТЗ обратно в запрос? Лишние перегонки данных с сервера 1С на сервер БД и обратно.
34 svchernova
 
16.06.15
14:21
(18) Лефмихалыч, у меня полная копия базы, только файловая
35 Dmitrii
 
гуру
16.06.15
14:21
(31) Видимо нужны все оплаты по каждому остатку. Хотя, скорее всего, достаточно было бы и Регистратор.
36 svchernova
 
16.06.15
14:22
(29) Хорошо, я попробую сейчас
37 svchernova
 
16.06.15
14:22
(31) Да, мне нужны ВСЕ оплаты по каждому остатку.
38 asady
 
16.06.15
14:23
(35) там и регистратор не используется
39 svchernova
 
16.06.15
14:25
(35), (38) Может быть, действительно регистратора достаточно. А вообще тема интересная, у меня пока не было подобных проблем, а тут, оказывается, всё не так -то просто
40 Dmitrii
 
гуру
16.06.15
14:26
(38) В запросе в (4) - не используется.
Но автор сказал, что сократил текст запроса, выкладывая его сюда. Я предполагаю, что в "полном" варианте все-таки используется.
Хотя, бог его знает, что там на самом деле. Может периодичность тут и вовсе не нужна.
41 svchernova
 
16.06.15
14:26
(9) не поняла, что ты имел ввиду :(
42 svchernova
 
16.06.15
14:28
Спасибо всем, кто откликнулся!
43 Dmitrii
 
гуру
16.06.15
14:28
(39) Если тебе нужна просто общая сумма оплаты, то периодичность не нужна.
Если необходимо получить детализацию по каждой оплате - нужна детализация.
В запросе в (4), учитывая, что делается группировка МАКСИМУМ(ТиповойОбороты.Период) КАК ДатаОплаты - получается берется только последняя дата оплаты. То есть достаточно детализации до Регистратор.
44 Dmitrii
 
гуру
16.06.15
14:30
(41) Он имел ввиду в (9) то же самое, что и я в (19)
Заменить ТиповойОстатки.Субконто1.* на ВЫРАЗИТЬ (ТиповойОстатки.Субконто1 КАК Справочник.Контрагенты).*

и так для каждого Субконто.
45 Dmitrii
 
гуру
16.06.15
14:31
(38) > там и регистратор не используется

Используется. Она берет последнюю дату оплаты. МАКСИМУМ(ТиповойОбороты.Период) КАК ДатаОплаты
46 svchernova
 
16.06.15
14:31
(43)Мне нужна детализация по каждой оплате. Ты прав, я в отчете показываю только последнюю дату оплаты ( я там вычисляю количество дней просрочки, дней со дня оплаты и тд). Но, тем не менее, я показываю на доп строчках те оплаты, которые были.
47 svchernova
 
16.06.15
14:32
(4) Поняла!
48 svchernova
 
16.06.15
14:33
ой поняла - это для (44)
49 rsv
 
16.06.15
14:33
(0) Уже выше излагали- разбейте на две временные и соединяйте.    Т.к. узнать что "тормозит "  в (0) нереально . Или выполнение соединения или сами подзапросы или то и  другое :)
50 svchernova
 
16.06.15
14:35
(49) Спасибо, я сейчас буду пробовать
51 svchernova
 
16.06.15
14:38
Спасибо всем большое!
52 svchernova
 
16.06.15
16:14
(49) Это снова я. Как-то не получается у меня на две временные разбить
53 svchernova
 
16.06.15
16:16
Вот такой код:
Запрос.Текст = "ВЫБРАТЬ
               |    ТиповойОстатки.Счет КАК Счет,
               |    ВЫРАЗИТЬ(ТиповойОстатки.Субконто1 КАК Справочник.Контрагенты) КАК Контрагент,
               |    ВЫРАЗИТЬ(ТиповойОстатки.Субконто1 КАК Справочник.Контрагенты).КБЕ КАК КБЕ,
               |    ВЫРАЗИТЬ(ТиповойОстатки.Субконто1 КАК Справочник.Контрагенты).ИдентификационныйКодЛичности КАК ИИН,
               |    ВЫРАЗИТЬ(ТиповойОстатки.Субконто2 КАК Справочник.ДоговорыКонтрагентов) КАК ДоговорКонтрагента,
               |    ВЫРАЗИТЬ(ТиповойОстатки.Субконто3 КАК Справочник.ВидСтрахования) КАК ВидСтрахования,
               |    ТиповойОстатки.Организация КАК Организация,
               |    ТиповойОстатки.СуммаОстаток КАК СуммаОстаток,
               |    ВЫРАЗИТЬ(ТиповойОстатки.Субконто2 КАК Справочник.ДоговорыКонтрагентов).ДатаДоговора КАК ДатаДоговора,
               |    ВЫРАЗИТЬ(ТиповойОстатки.Субконто2 КАК Справочник.ДоговорыКонтрагентов).ДатаНачалаДействияДоговора КАК ДатаНачала,
               |    ВЫРАЗИТЬ(ТиповойОстатки.Субконто2 КАК Справочник.ДоговорыКонтрагентов).ДатаОкончанияДействияДоговора КАК ДатаОкончания,
               |    0 КАК СтраховаяПремия,
               |    ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяССылка) КАК Посредник,
               |    0 КАК ПризнакДопДата,
               |    NULL КАК СуммаОборот,
               |    NULL КАК Период
               |ПОМЕСТИТЬ ВТ_Остатки
               |ИЗ
               |    РегистрБухгалтерии.Типовой.Остатки(&ДатаКон, Счет = &С128041, , Организация В (&СписокОрганизаций)) КАК ТиповойОстатки
               |
               |ОБЪЕДИНИТЬ ВСЕ
               |
               |ВЫБРАТЬ
               |    NULL,
               |    ВЫРАЗИТЬ(ТиповойОбороты.КорСубконто1 КАК Справочник.Контрагенты),
               |    NULL,
               |    NULL,
               |    ВЫРАЗИТЬ(ТиповойОбороты.КорСубконто1 КАК Справочник.ДоговорыКонтрагентов),
               |    ВЫРАЗИТЬ(ТиповойОбороты.КорСубконто3 КАК Справочник.ВидСтрахования),
               |    ТиповойОбороты.Организация,
               |    NULL,
               |    NULL,
               |    NULL,
               |    NULL,
               |    NULL,
               |    NULL,
               |    NULL,
               |    СУММА(ТиповойОбороты.СуммаОборот),
               |    МАКСИМУМ(ТиповойОбороты.Период)
               |ИЗ
               |    РегистрБухгалтерии.Типовой.Обороты(, &ДатаКон, Регистратор, Счет В (&СчетаОплаты), , Организация В (&СписокОрганизаций), КорСчет В (&Корсчет), ) КАК ТиповойОбороты
               |
               |СГРУППИРОВАТЬ ПО
               |    ТиповойОбороты.Организация,
               |    ВЫРАЗИТЬ(ТиповойОбороты.КорСубконто1 КАК Справочник.ДоговорыКонтрагентов),
               |    ВЫРАЗИТЬ(ТиповойОбороты.КорСубконто1 КАК Справочник.Контрагенты),
               |    ВЫРАЗИТЬ(ТиповойОбороты.КорСубконто3 КАК Справочник.ВидСтрахования)";
54 Dmitrii
 
гуру
17.06.15
09:58
(53) Кроме использования выражения ВЫРАЗИТЬ ни одним из других рекомендаций вы не воспользовались, пропустив их мимо ушей.
Нафига тут объединение?...
Суть создания ВТ_Остатки состоит в том, чтобы была возможность использования данных из этой таблицы при выполнении запроса к ТиповойОбороты в параметрах виртуальной таблицы.
Вы же создали ВТ_Остатки и объединили весь результат туда.