Имя: Пароль:
1C
 
Пакетные запросы быстрее работают?
0 IamAlexy
 
28.02.10
11:21
собственно сабж.

для 8.2 рекомендовали вроде бы максимально использовать именно пакетные запросы а не левые соединения к виртуальным таблицам например остатков с отборами..
1 Garkin
 
28.02.10
11:26
(0) Не вижу причин по которым они должны работать медленнее.
2 IamAlexy
 
28.02.10
11:27
вопрос звучит так:

очертя голову кинуться и резко все запросы переделать на пакетны дабы пожать 10% роста быстродействия... или забить болт и пойти пить пиво?
3 Волшебник
 
28.02.10
11:28
забить болт и пойти пить пиво
4 Garkin
 
28.02.10
11:29
(3) +1,
Тем более, воскресенье.
5 ДенисЧ
 
28.02.10
11:29
Сначала пиво, потом болт, потом запросы.
6 IamAlexy
 
28.02.10
11:31
(4)  я так развлекаюсь :) по этому мне не принципиально
7 IamAlexy
 
28.02.10
11:31
(5) логично
8 МихаилМ
 
28.02.10
11:43
у разных субд, разные стратегии исполнения запросов.
так что говорить имеет смысл только в контексте конкретной субд.
9 IamAlexy
 
28.02.10
11:44
(8) MSSQL
10 IamAlexy
 
28.02.10
11:44
2008ач
11 Fragster
 
гуру
28.02.10
11:45
(5) потом пароли менять полагается!
12 IamAlexy
 
28.02.10
11:46
(11) паролями пусть 0дмины занимаются
13 Masquerade
 
28.02.10
11:49
(8)
В контексте каких СУБД ты готов говорить о различиях пакетных запросов в отношении к левым соединениям?
14 Fragster
 
гуру
28.02.10
11:50
(12) ну пароли в 1ску
15 Aleksey_3
 
28.02.10
12:00
16 IamAlexy
 
28.02.10
12:01
Service Temporarily Unavailable

The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.

Apache Server at devtrainingforum.v8.1c.ru Port 80
17 Aleksey_3
 
28.02.10
12:07
А я думал, это у меня так. Значит завтра админы 1С придут на работу, пнут сервера, и будет доступ
18 Aleksey_3
 
28.02.10
12:08
Временные таблицы vs   пакетные запросы

11.01.2009 10:43 Булыгин Антон

Использование пакетных запросов = использование временных таблиц или нет?
19 IamAlexy
 
28.02.10
12:11
эх и у гугля в кеше нет этой странички
20 Jolly Roger
 
28.02.10
12:17
(0) в чем противоречие между пакетными запросами и левыми соединениями?
21 IamAlexy
 
28.02.10
12:18
хз.. но почему то пакетный запрос у меня работает в 2 раза дольше левого соединения.
причем результат работы естественно одинаковый.
22 IamAlexy
 
28.02.10
12:20
блин
23 IamAlexy
 
28.02.10
12:20
походу сервак кеширует
24 IamAlexy
 
28.02.10
12:24
это действительно странно..

беру для примера документик.
в нем 1600 строк.
при проведении собираются остатки по пяти счетам.
собираются одним запросом.

если запрос пакетный то выполняется 13 секунд
если с левыми соединениями то 11 секунд
25 H A D G E H O G s
 
28.02.10
12:38
Я уже приводил выкладки.
Пакетные запросы не дают повышения производительности, сами по себе.
Они дают доп. фильтр для виртуальных таблиц
26 shuhard
 
28.02.10
12:42
(24) чё гадать
есть профайлер и план запроса
27 IamAlexy
 
28.02.10
12:42
спасибо.

то есть если у меня условие простое - например просто отбор измерения по списку.. которое вполне в условие виртуальной таблицы ложится - то мне вообще должно быть без разницы ?
28 Zeldan
 
28.02.10
12:44
(0) на личном опыте,тестировал сложный запрос с большим количеством вложенных и аналогичный переписанный пакетный.В скорости проигрывает пакетный, на 10-15%,а в плане понимания пакетные экономит кучу времени.Так что особо не заморачивайся...
29 IamAlexy
 
28.02.10
12:46
гы... я пока делал пакетный запрос нашел где у меня в непакетном неоптимально сделано..

оптимизировал и теперь непакетный работает быстрее пакетного :)

в итоге - в документе сделал флажок который переключает запрос при проведении в пакетный или в простой...

завтра буду у клиента - покажу пользователям пусть поиграются и свое СУБЪЕКТИВНОЕ мнение выскажут - чисто ради интереса :)
30 NcSteel
 
28.02.10
14:46
(0) Судя по рекомендациям 1с то значительно может скорость возрости .
31 IamAlexy
 
28.02.10
15:00
(30) где бы еще эти рекомендации почитать
32 H A D G E H O G s
 
28.02.10
15:13
(30) Мозг надо использовать, а не рекомендациям следовать.
33 H A D G E H O G s
 
28.02.10
15:14
ВЫБРАТЬ // Запрос, контролирующий остатки на складах
   Док.Номенклатура                                              КАК Номенклатура,
   Док.Номенклатура.Представление                                КАК НоменклатураПредставление,
   Док.Номенклатура.ЕдиницаХраненияОстатков.Представление        КАК ЕдиницаХраненияОстатковПредставление,
  Док.ХарактеристикаНоменклатуры                                КАК ХарактеристикаНоменклатуры,
   ПРЕДСТАВЛЕНИЕ(Док.ХарактеристикаНоменклатуры)                КАК ХарактеристикаНоменклатурыПредставление,
  Док.СерияНоменклатуры                                        КАК СерияНоменклатуры,
   ПРЕДСТАВЛЕНИЕ(Док.СерияНоменклатуры)                        КАК СерияНоменклатурыПредставление,
  Док.Склад                                            КАК Склад,
  Док.Качество                                        КАК Качество,
  СУММА(ВЫРАЗИТЬ(Док.Количество * Док.Коэффициент /Док.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент КАК Число(15,3)))
                                                               КАК ДокументКоличество,
   ЕстьNull(МАКСИМУМ(ОстаткиБезСерии.КоличествоОстаток),0)     КАК ОстатокБезСерииКоличество,
   ЕстьNull(МАКСИМУМ(Остатки.КоличествоОстаток),0)             КАК ОстатокКоличество,
   ЕстьNull(МАКСИМУМ(Резервы.КоличествоОстаток),0)             КАК РезервыКоличество,
   0                              КАК РезервыПоСерииКоличество,
   ЕстьNull(МАКСИМУМ(ТоварыКПередаче.КоличествоОстаток),0)     КАК КПередачеКоличество,
   ЕстьNull(МАКСИМУМ(ТоварыКПередачеБезСерии.КоличествоОстаток),0) КАК КПередачеБезСерииКоличество,
   ЕстьNull(Максимум(РезервыПоДокументу.КоличествоОстаток),0)                        КАК РезервыПоДокументуКоличество,
   0                КАК РезервыПоДокументуБезСерииКоличество,
   0                                                            КАК КПолучению,
   0                                                            КАК КПолучениюПоДокументуКоличество,
   0                                                            КАК КПередачеПоДокументуКоличество,
   0                                                              КАК КПередачеПоДокументуБезСерииКоличество
ИЗ
   
   Документ.РеализацияТоваровУслуг.Товары
КАК Док

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

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


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

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

ГДЕ
   Док.Ссылка  =  &ДокументСсылка
   И Не Док.Номенклатура.Комплект
   И Не Док.Номенклатура.Услуга
   И Док.Склад.ВидСклада<>&НТТ И Док.Склад.ВидСклада<>&Розничный
СГРУППИРОВАТЬ ПО

   Док.Номенклатура,
  Док.ХарактеристикаНоменклатуры,
  Док.СерияНоменклатуры,
  Док.Качество,                                    
   Док.Склад

ДЛЯ ИЗМЕНЕНИЯ РегистрНакопления.ТоварыНаСкладах.Остатки // Блокирующие чтение таблицы остатков регистра для разрешения коллизий многопользовательской работы

ИТОГИ СУММА (ДокументКоличество), МАКСИМУМ(ОстатокБезСерииКоличество), МАКСИМУМ(РезервыКоличество),
        МАКСИМУМ(КПередачеКоличество), МАКСИМУМ(РезервыПоДокументуКоличество), Максимум(РезервыПоСерииКоличество),
       Максимум(КПередачеБезСерииКоличество), МАКСИМУМ(РезервыПоДокументуБезСерииКоличество),
       Максимум(КПолучению), Максимум(КПередачеПоДокументуКоличество), Максимум(КПередачеПоДокументуБезСерииКоличество), Максимум(КПолучениюПоДокументуКоличество)
ПО Номенклатура,
  ХарактеристикаНоменклатуры,
   Склад
   ,Качество
34 H A D G E H O G s
 
28.02.10
15:15
(33) Я хочу верить в то, что в (33) SQL догадается оптимизировать и 1 раз выборку номенклатур сделать, но подстраховался бы и сделал бы выборку 1 раз сам в ВР.
35 H A D G E H O G s
 
28.02.10
15:18
А вообще - классика - ТЧ документа ЛевымСоединением с Вирт. таблицы остатков.

В параметры ВТ список номенклатур передать нельзя - поэтому предварительно строим Временную таблицу из ТЧ документа, и уже работаем с ней, в качестве основной.
36 IamAlexy
 
28.02.10
15:19
(35) почему нельзя ?
предварительно выгружаем номенклатуру в массив  и параметром запроса его...
37 H A D G E H O G s
 
28.02.10
15:31
(36) Это противоестественно, согласно методологии 1С.
Уже столько холиваров было, ты где был?
38 IamAlexy
 
28.02.10
15:32
(37) в луносрачах ср.лся...

тезисно: почему нельзя?
39 H A D G E H O G s
 
28.02.10
15:36
(38) <<Просто за время пути - собачка могла подрасти>>.
Смысл - данные для остатков должны браться из БД. И точка. Вдруг будет несоответствие между ТЧ документа на клиенте и ТЧ документа в базе (труднореализуемый вариант, конечно).
40 IamAlexy
 
28.02.10
15:38
(39)а.
а разве проведение не в транзакции делается
и если запрос делается при проведении могут данные изменится ?
41 NcSteel
 
28.02.10
15:54
(32) Мозг всегда надо иметь, не понял твоего высказывания.
42 NcSteel
 
28.02.10
15:55
(40) Запросто.
43 NcSteel
 
28.02.10
15:55
(31) В книге знания 1с .
44 IamAlexy
 
28.02.10
15:56
(43) что за "книга знания 1с" ?
45 NcSteel
 
28.02.10
16:00
46 IamAlexy
 
28.02.10
16:05
(45) спасибо добрый человек.
пользовательский раздел книги очень и очень интересен.
47 NcSteel
 
28.02.10
16:09
Cоединения с виртуальными таблицами

Рекомендации

Если в запросе используется соединение с виртуальной таблицей языка запросов 1С:Предприятия (например, "РегистрНакопления.Товары.Остатки()") и запрос работает с неудовлетворительной производительностью, то рекомендуется вынести обращение к виртуальной таблице в отдельный запрос с сохранением результатов во временной таблице.
То есть, следует использовать ту же рекомендацию, что и в случае соединения с подзапросом.
Пояснения

Виртуальные таблицы, используемые в языке запросов 1С:Предприятия, могут разворачиваться в подзапросы при трансляции в язык SQL. Это связано с тем, что виртуальная таблица часто (но не всегда) получает данные из нескольких физических таблиц СУБД. Если вы используете соединение с виртуальной таблицей, то на уровне SQL оно может быть в некоторых случаях реализовано, как соединение с подзапросом. В этом случае оптимизатор СУБД может точно так же выбрать неоптимальный план, как при работе с подзапросом, использованным в языке 1С:Предприятия в явном виде.

Например
48 NcSteel
 
28.02.10
16:09
оединения с подзапросами

Рекомендации

При написании запросов не следует использовать соединения с подзапросами. Следует соединять друг с другом только объекты метаданных или временные таблицы. Если запрос использует соединения с подзапросами, то его следует переписать с использованием временных таблиц.

Если запрос содержит соединения с подзапросами, то это может привести к следующим негативным последствиям:
Крайне медленное выполнение запроса при слабой загрузке серверного оборудования. Замедление запроса может быть очень значительным (до нескольких порядков).
Нестабильная работа запроса. При некоторых условиях запрос может работать достаточно быстро, при других - очень медленно.
Значительная разница по времени выполнения запроса на разных СУБД.
Повышенная чувствительность запроса к актуальности и полноте статистик. Сразу после полного обновления статистик запрос может работать быстро, но через некоторое время опять замедлиться.
Пример потенциально опасного запроса, использующего соединение с подзапросом:

ВЫБРАТЬ ...
ИЗ Документ.РеализацияТоваровУслуг
ЛЕВОЕ СОЕДИНЕНИЕ (
  ВЫБРАТЬ ИЗ РегистрСведений.Лимиты
  ГДЕ ...
  СГРУППИРОВАТЬ ПО ...
) ПО ...

В данном примере в правой части соединения используется подзапрос, а не объект метаданных. Обратите внимание на то, что в какой части соединения (правой или левой) используется подзапрос - не важно. Точно так же не важно, какого типа соединение указано (ЛЕВОЕ, ПРАВОЕ и т.д.). Во всех случаях такая конструкция является потенциально опасной и должна быть исправлена при помощи временных таблиц.

Обратите внимание на то, что возможность использования временных таблиц появилась в 1С:Предприятии начиная с версии 8.1. Если вы используете версию 8.0, то для решения проблемы производительности такого запроса следует перейти на 8.1.

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

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

Для вышеприведенного примера получится следующий пакетный запрос:

// Создать менеджер временных таблиц
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
// Текст пакетного запроса
Запрос.Текст = "
 // Заполняем временную таблицу. Запрос к регистру лимитов.
  | ВЫБРАТЬ ...
  | ПОМЕСТИТЬ Лимиты
  | ИЗ РегистрСведений.Лимиты
  | ГДЕ ...
  | СГРУППИРОВАТЬ ПО ...
  | ИНДЕКСИРОВАТЬ ПО ...;
 
 // Выполняем основной запрос с использованием временной таблицы
  ВЫБРАТЬ ...
  ИЗ Документ.РеализацияТоваровУслуг
  ЛЕВОЕ СОЕДИНЕНИЕ Лимиты
  ПО ...;"
Пояснения

Во встроенном языке запросов 1С:Предприятия версии 8.0 отсутствовала возможность использовать временные таблицы и писать пакетные запросы. При этом часто было необходимо выполнять сложные вычисления в рамках одного запроса (то есть, одного цикла взаимодействия клиент - сервер 1С:Предприятия - сервер СУБД). Для решения таких задач использовались подзапросы - обращения не к объектам метаданных, а к выборкам из этих объектов. Как правило, подзапросы выполнялись с группировкой и часто использовались в соедениниях.

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

Переписывание запроса по приведенной выше методике имеет своей целью упростить работу оптимизатору СУБД. В переписанном запросе все выборки, участвующие в соединениях будут представлять собой физические таблицы, и СУБД сможет легко определить размер каждой выборки. Это позволит СУБД гарантированно выбрать самый быстрый из всех возможных планов. Причем, СУБД будет делать правильный выбор независимо ни от каких условий. Переписанный подобным образом запрос будет работать одинаково хорошо на любых СУБД, что особенно важно при разработке тиражных решений. Кроме того, переписанный подобным образом запрос лучше читается, проще для понимания и отладки.

Следует понимать, что переписав запрос таким образом, мы, возможно, внесли в него некоторое замедление за счет дополнительных накладных расходов - создания временных таблиц. Если СУБД не ошибется с выбором плана, то она, возможно, выполнит старый запрос быстрее, чем новый. Однако, это замедление всегда будет крайне незначительным. Размер замедления зависит от используемой СУБД и производительности оборудования. В типичном случае на создание одной временной таблицы может уйти несколько миллисекунд. То есть, эти замедления не могут оказать заметного влияния на производительность системы и как правило ими можно пренебречь.
49 IamAlexy
 
28.02.10
16:10
(48) еще раз огромное спасибо.. действительно очень умная статья

видимо придется срочно кинутся и переделать запросы на правильные
50 NcSteel
 
28.02.10
16:10
Использование подзапросов в условии соединения

Рекомендации

Не следует использовать подзапросы в условии соединения. Это может привести к значительному замедлению запроса и (в отдельных случаях) к его полной неработоспособности на некоторых СУБД. Пример запроса с использованием подзапроса в условии соединения:

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

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

Запрос.Текст = "
 // Максимальные даты установки цен в прошлом периоде для данных номенклатур
  |ВЫБРАТЬ
  | ОстаткиТоваров.Номенклатура КАК Номенклатура,
  | МАКСИМУМ(Цены.Период) КАК Период
  |ПОМЕСТИТЬ ДатыПоНоменклатурам
  |ИЗ
  | РегистрНакопления.ТоварыНаСкладах.Остатки(...) КАК ОстаткиТоваров
  | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цена КАК Цены
  | ПО Цены.Номенклатура = ОстаткиТоваров.Номенклатура И
  | Цены.Период < НАЧАЛОПЕРИОДА(ОстаткиТоваров.Период, МЕСЯЦ)
  | СГРУППИРОВАТЬ ПО ОстаткиТоваров.Номенклатура
  | ГДЕ ОстаткиТоваров.Склад = &Склад;
 
 // Выбрать данные по цене за найденный период
  |ВЫБРАТЬ
  | ДатыПоНоменклатурам.Номенклатура КАК Номенклатура,
  | Цены.Цена КАК ЦенаПрошлогоМесяца
  |ИЗ ДатыПоНоменклатурам
  | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Цена КАК Цены
  | ПО Цены.Номенклатура = ОстаткиТоваров.Номенклатура И
  | Цены.Период = ДатыПоНоменклатурам.Период
";
51 IamAlexy
 
28.02.10
16:10
понравился пример:

данном запросе используется обращение к реквизитам регистратора. Регистратор является полем составного типа, которое может принимать значения ссылки на один из 56 видов документов.

Запрос.Текст = "ВЫБРАТЬ
|    Продажи.Регистратор.Номер,
|    Продажи.Регистратор.Дата,
|    Продажи.Контрагент,
|    Продажи.Количество,
|    Продажи.Стоимость
|ИЗ
|    РегистрНакопления.Продажи КАК Продажи
|ГДЕ ...

SQL-текст этого запроса будет включать 56 левых соединений с таблицами документов. Это может привести к серьезным проблемам производительности при выполнении запроса.
52 NcSteel
 
28.02.10
16:12
(51) Все же нашел пароль ))) . а то хотел уже и этот текст копипастить.
53 IamAlexy
 
28.02.10
16:12
(52) кстати - у меня то пользовательский доступ..
а он отличается от доступа разработчиков ?
в плане содержание КБ одинаковое ?
54 NcSteel
 
28.02.10
16:13
(53) не знаю ))) .

Рубрикатор

 Проблемы и решения
 Методики
 Инструкции
 Техническая информация
 Администрирование
 Стандарты разработки

Вот видимые разделы.
55 IamAlexy
 
28.02.10
16:14
вроде такие же
56 NcSteel
 
28.02.10
16:15
Я бы не рекомендовал кидаться переделывать запросы . так как оптимизировать можно всю жизнь . А вот при появлении проблем с производительностью можно и покопаться.
57 IamAlexy
 
28.02.10
16:16
(56) так щас только этим и занимаюсь - повышением производительности.. вот до запросов добрался :)
58 NcSteel
 
28.02.10
16:20
А ну тогда удачи в этом действительно не легком деле !,
59 Jolly Roger
 
28.02.10
17:12
казалось бы, причем здесь пакетные запросы?..
60 IamAlexy
 
28.02.10
17:19
(59) (0) почитай.
ветка про них же
61 Jolly Roger
 
28.02.10
17:22
(60) прочитал, ответа на (20) нет...
62 NcSteel
 
28.02.10
17:45
(61) В статье подробно описано.
63 Jolly Roger
 
28.02.10
18:21
(62) не понял, про какую статью речь.
процитируй, если не сложно, определение пакетного запроса...
64 IamAlexy
 
28.02.10
18:25
65 Jolly Roger
 
28.02.10
18:47
(64) бугага! хочешь, напишу пакетный запрос без единой временной таблицы?
66 NcSteel
 
28.02.10
18:51
(65) И ?
67 Jolly Roger
 
28.02.10
18:52
(66) "пакетный запрос" != "запрос с временными таблицами". только и всего. мелочь, вобщем-то...
68 NcSteel
 
28.02.10
18:55
(67) Автора интересовал вариант пакетного запроса с временными таблицами. Темболее  даже без временных таблиц пакетный запрос предпочтительнее.
69 Jolly Roger
 
28.02.10
18:57
(68) остается, только, объяснить это автору...
70 IamAlexy
 
28.02.10
19:31
(69) автор это понимает.
и в (0) вроде задан вопрос вполне корректно...

хотя стоп.. может ты путаешь виртуальные таблицы и временные?
71 Aleksey_3
 
28.02.10
19:57
Ссылка из (15) заработала
72 IamAlexy
 
28.02.10
20:02
(71) там ничего полезного.
а все что нужно нашел в (64)
73 Jolly Roger
 
28.02.10
20:09
(70) да нет, я не путаю. я все сказал в (67) :-)
74 IamAlexy
 
28.02.10
20:10
(73) и какое это имеет отношение к (0) ?
75 Sammo
 
28.02.10
20:14
Путем использования пакетна запросов можно управлять тем - какой план запроса созласт SQL
76 Jolly Roger
 
28.02.10
20:25
(74) в (0) ни разу не упоминается временная таблица. не говоря уж о заголовке...
при этом, речь ведешь о скорости запросов именно с временными таблицами. пакетный запрос вовсе не подразумевает в нем наличия временной таблицы...
77 IamAlexy
 
28.02.10
20:59
(76) буквоед детектед :)

за 70 постов ты первый к этому придрался.
все остальные все поняли...
78 Drx211
 
28.02.10
21:28
(0)Вопрос звучит не верно, пакетные запросы надо использовать тогда - когда надо :) Но естественно - если последовательно выполняется несколько запросов, и есть возможность объединить их в один пакетный - то надо это делать.
Если работать без пакета - то будут накладные расходы - по инициализации выполнения запроса, плюс перегон данных на сервер и обратно. В случае пакетного запроса - все это делается в разы быстрее.
79 Drx211
 
28.02.10
21:29
(76)Не то, чтобы не подразумевает, но очень часто это и является основным преимуществом - пример: создается 3 разных ВТ, и далее совместно обрабатываются(объединени, соединени и т.п.) - и все это делается одним запросом.
80 IamAlexy
 
28.02.10
21:50
(78) для буквоедов переведу (0):

использование чего более оправдано например для сбора остатков для номенклатуры заполненной в табличной части документа: ПАКЕТА запросов с созданием временных таблиц и выборкой данных из оной последним запросом пакета или один запрос с левым соединением к виртуальной таблице остатков.

зы:хотя до вас двоих все вполне все поняли.
81 Drx211
 
28.02.10
22:10
Судя по (80)в (78),(79) распинался зря(хотя написал то все вроде понятно и подробно)... примерно понятно, что вы имеете в виду, а так-же - что человек "не в теме"... больше тему засорять не буду :) если что - см. H A D G E H O G s, он вроде тоже объяснить пытался
82 IamAlexy
 
28.02.10
22:17
(81) он вообще то объяснял другое. а по теме высказался однозначно в (25)
83 NcSteel
 
28.02.10
23:26
(82) Причем в (25) он в принципе не прав.
84 IamAlexy
 
28.02.10
23:29
(83) хз.. на тестовом своем примере я пока вижу на что  1 секунду дольше работает именно пакетный  запрос с виртуальными таблицами..

но я типа нарушаю все моральные и этические принципы 1С - я массив для фильтра в виртуальных таблицах (к которым левое соединение делается) делаю перед запросом и потом тупо его в качестве параметра передаю в таблицу.
85 NcSteel
 
28.02.10
23:32
(84) Если создавать вложенные запросы , то скуль (думаю в файловом режиме как раз вложенные запросы рулят) может некорректно построить выполнение запроса и тогда для каждой строки будет выполняться большая выборка из базы, но временные таблицы при больших выборках занимают доли секунды для создания собственно таблиц на Скуле.
86 NcSteel
 
28.02.10
23:33
(85) + Поэтому надо корректно выбрать вариант оптимизации.
87 TigerPXN
 
28.02.10
23:36
(80) Еще интересно, что быстрее:
1) пакетный запрос;
2) а) сначала выполняем запрос по ТЧ документа;
  б) выгружаем из полученного результата колонку с номенклатурой в массив;
  в) делаем запрос по виртуальной таблице остатков, но вообще без объединения, используя фильтр по массиву номенклатуры;
  г) далее обрабатываем обе полученные таблицы "ручками" как в старые добрые времена.
По идее, запросы во втором варианте намного проще. И никаких лишних таблиц на диске не создается. Но зато есть накладные расходы по инициализации двух запросов вместо одного и затраты на "ручную" обработку таблиц. Я думаю, если мощность рабочей станции сопоставима с мощностью сервера, то второй вариант вполне может быть быстрее. Особенно, если размеры таблиц небольшие - до нескольких десятков записей (что можно считать типичным случаем).
88 Aleksey_3
 
28.02.10
23:37
Пакетные запросы. Автор Павел Чистов
(с) http://www.nashe1c.ru/materials-view.jsp?id=47
89 IamAlexy
 
28.02.10
23:37
(87) мощность рабочей станции не рассматривается вообще ибо в планах переезд в управляемый режим
90 Поручик
 
28.02.10
23:37
Блин, токо хотел запостить ссылку
91 TigerPXN
 
28.02.10
23:40
(89) Тем более. Вопрос только в том, насколько быстрее делается объединение средствами SQL, чем при помощи методов ТЗ "Найти". Думаю, в случае небольших таблиц этой разницей можно принебречь. Она будет меньше, чем время физического создания временной таблицы на диске.
92 IamAlexy
 
28.02.10
23:44
(88) ссылка не дает главного - не говорит однозначно и безповоротно - что быстрее :)
93 TigerPXN
 
28.02.10
23:44
+(91) А если совсем уж оптимизировать, то, думаю, оптимальным будет использование разных алгоритмов для разного количества строк в документе. :)
94 IamAlexy
 
28.02.10
23:44
(93) чушь
95 NcSteel
 
28.02.10
23:45
(87) Данный вариант будет медленнее чем пакетный запрос.
96 TigerPXN
 
28.02.10
23:45
(95) Почему? Кто-нибудь проверял?
97 NcSteel
 
28.02.10
23:46
(91) Да работать с ТЗ на клиенте в принципе может в неокторых случаях быть быстрее чем запрос.
98 NcSteel
 
28.02.10
23:47
(96) Достаточно логику включить .

В твоем варианте несколько обращений к серверу .
99 TigerPXN
 
28.02.10
23:48
(98) Можно все сделать в одной процедуре, которая будет выполняться на сервере.
100 IamAlexy
 
28.02.10
23:48
(97) ну да.
учитывая что в моем примере в документе 1600 строк, запрос по остаткам делается к шести счетам...
а на счетах остатки 1.6 млн. различных субконто

действительно - перебор на клиенте это будет то что нужно :)
101 TigerPXN
 
28.02.10
23:48
Мой вариант предполагает большую нагрузку на процессор и меньшую - на винт. По-моему, это вполне разумно.
102 IamAlexy
 
28.02.10
23:49
(99) ну хз.. у меня сейчас по отладчику подготовка массива для фильтра виртуальных таблиц с очисткой оного от дублей и пустых значений  делается дольше чем сам запрос :)
103 IamAlexy
 
28.02.10
23:50
(101) память не резиновая, таблицы ворочать бесконечно в оной.. темболее что еще ее SQL жрет неподетски..
104 TigerPXN
 
28.02.10
23:55
(102) А если получать массив отдельным запросом к ТЧ документа с флагом "Различные" и отбором "кроме пустых"? Не быстрее ли будет?
105 IamAlexy
 
01.03.10
00:05
(104) и тебе спасибо добрый человек.
включение запроса к ТЧ для подготовки фильтра в пакетный запрос - сделала идеальное еще более идеальным.
106 TigerPXN
 
01.03.10
00:26
(105) Ну так на чем остановился? Используешь пакетные запросы или оставил все на объединениях?
Кстати, тестировать интересно не только на одном документе с 1600 строк, но и на 1600 документах с 1 строкой.
107 IamAlexy
 
01.03.10
00:27
(106) пакетные делаю
и красиво и быстро.

а по поводу "тестировать надо...."

прикол в том что у меня документов по 1 строке практически не будет.. а вот документы от 1000 строк это да - это сколько угодно...
108 IamAlexy
 
01.03.10
00:30
проведение документа - 11 секунд.
пользователи завтра оргазмировать будут
109 agarych
 
03.03.10
16:47
(108) Давай запрос в студию, посмотрю поучусь. Я просто сейчас тоже все тут у себя оптимизирую )
110 Masquerade
 
03.03.10
19:08
Пакетные запросы - да это ж просто праздник какой-то! С сорока секунд до 1-ой - обалдеть.
111 1c_asp
 
03.03.10
19:15
На мой взгляд в разных случаях возможны разные варианты :
Может оптимизатору SQL удастся оптимизировать запрос и выполнить его эффективней без обращения к диску для создания временной таблицы. А может оптимизатору сорвет крышу от сложного запроса и быстрее будет с временными таблицами.

Временные таблицы тоже ведь жрут нормально ресурсов. Сервер их может кидать на диск, в tempdb, а это серьезные затраты ресурсов
112 1c_asp
 
03.03.10
19:16
(97) Причем может быть быстрее на порядки
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.