|   |   | 
| 
 | как оптимизировать запрос | ☑ | ||
|---|---|---|---|---|
| 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) Кроме использования выражения ВЫРАЗИТЬ ни одним из других рекомендаций вы не воспользовались, пропустив их мимо ушей.
 Нафига тут объединение?... Суть создания ВТ_Остатки состоит в том, чтобы была возможность использования данных из этой таблицы при выполнении запроса к ТиповойОбороты в параметрах виртуальной таблицы. Вы же создали ВТ_Остатки и объединили весь результат туда. | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |