Имя: Пароль:
1C
1С v8
Оптимален ли запрос?
0 DIvanmgn
 
12.04.12
09:21
ВЫБРАТЬ
   ВложенныйЗапрос.Номенклатура,
   ВложенныйЗапрос.Количество
ИЗ
   (ВЫБРАТЬ
       ВложенныйЗапрос.Номенклатура КАК Номенклатура,
       ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток, 0) КАК Количество
   ИЗ
       (ВЫБРАТЬ
           Номенклатура.Ссылка КАК Номенклатура
       ИЗ
           Справочник.Номенклатура КАК Номенклатура
       ГДЕ
           (НЕ Номенклатура.ПометкаУдаления)
           И (НЕ Номенклатура.ЭтоГруппа)
           И Номенклатура.Ссылка В ИЕРАРХИИ(&Группа)) КАК ВложенныйЗапрос
           ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата, Склад = &Склад) КАК ТоварыНаСкладахОстатки
           ПО ВложенныйЗапрос.Номенклатура = ТоварыНаСкладахОстатки.Номенклатура) КАК ВложенныйЗапрос
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Обороты(&Дата1, &Дата2, , Склад = &Склад) КАК ТоварыНаСкладахОбороты
       ПО ВложенныйЗапрос.Номенклатура = ТоварыНаСкладахОбороты.Номенклатура

Выполняется около минуты за годовой период.

Посоветуйте пожалуйста как оптимизировать?
1 vmv
 
12.04.12
09:22
написан красиво по буквам, но г по исполнению - очевидно
2 IKSparrow
 
12.04.12
09:22
Временные таблицы, индексы, пакетный запрос. И будет тебе счастье.
3 vmv
 
12.04.12
09:23
при выборке каждой записи делать рекурсивную выбору всех записей, а потом еще одну - это питерка, без базара
4 Александр_
Тверь
 
12.04.12
09:24
ппц а не запрос :)
5 Александр_
Тверь
 
12.04.12
09:26
слушай, может ты лучше скажешь, что ты хотел получить?
6 Плот
 
12.04.12
09:26
(0) Вложенные запросы это зло. Используй временные таблицы.
7 vmv
 
12.04.12
09:28
я думаю автор счас собереться и поступит как мужчина, т.е. внятно и искренне опишет постановку задачи, чо ото стесняцца - самое страшное позади - мелом уже посыпали, будем искать оптиму
8 azernot
 
12.04.12
09:29
ВЫБРАТЬ
   Номенклатура.Ссылка КАК Номенклатура
ПОМЕСТИТЬ СпрНоменклатура
ИЗ
   Справочник.Номенклатура КАК Номенклатура
ГДЕ
   (НЕ Номенклатура.ПометкаУдаления)
   И (НЕ Номенклатура.ЭтоГруппа)
   И Номенклатура.Ссылка В ИЕРАРХИИ(&Группа)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ТоварыНаСкладахОстатки.Номенклатура,
   ТоварыНаСкладахОстатки.КоличествоОстаток,
   ТоварыНаСкладахОбороты.КоличествоПриход,
   ТоварыНаСкладахОбороты.КоличествоРасход
ИЗ
   РегистрНакопления.ТоварыНаСкладах.Остатки(
           &Дата,
           Склад = &Склад
               И Номенклатура В
                   (ВЫБРАТЬ
                       СпрНоменклтура.Номенклатура
                   ИЗ
                       СпрНоменклтура)) КАК ТоварыНаСкладахОстатки
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Обороты(
               &Дата1,
               &Дата2,
               ,
               Склад = &Склад
                   И Номенклатура В
                       (ВЫБРАТЬ
                           СпрНоменклтура.Номенклатура
                       ИЗ
                           СпрНоменклтура)) КАК ТоварыНаСкладахОбороты
       ПО ТоварыНаСкладахОстатки.Номенклатура = ТоварыНаСкладахОбороты.Номенклатура
9 azernot
 
12.04.12
09:31
+(8) Это я исхожу из того, что реально нужен остаток на Одну &Дата, а оборот за друго
10 Sewace
 
12.04.12
09:31
(0)
Дело не во вложенных запросах - в них ничего плохого не вижу.
А вот конкретно данный запрос неоптимален по следующей причине.
Я так понимаю, надо выбрать остатки из РН по заданному критерию. Зачем в памяти соединять всю таблицу остатков с номенклатурой, а потом отбирать нужные записи по условиям.
Можно выполнить единственную выборку из виртуальной таблицы остатков с параметрами. Тогда с сервера вернется уже отфильтрованная таблица.
11 azernot
 
12.04.12
09:31
й период &Дата1 и &Дата2
Нужны данные только по тем товарам, которые имеют и остаток и оборот.
12 DIvanmgn
 
12.04.12
09:35
(10) Можно выполнить единственную выборку из виртуальной таблицы остатков с параметрами. Тогда с сервера вернется уже отфильтрованная таблица.

тут немного подробнее если можно.
13 DIvanmgn
 
12.04.12
09:35
(8) на производительности не сказалось - примерно то же время.
14 azernot
 
12.04.12
09:36
(13) Если ты смотршь на 10 номенклатурах и на базе с 100 документов, то ты и не заметишь разницы :)
15 DIvanmgn
 
12.04.12
09:37
(7) задача - заполнить документ товаром, который двигался по определенному складу, в течении заданного периода, и заполнить остатком этого товара на сегодняшний день.
16 azernot
 
12.04.12
09:39
(15) Зачем тогда отбор по группе номенклатуры? А если остаток имеет помеченный на удаление товар?
Вообще же, с этой точки зрения запрос из (8) оптимален. Разве что поля оборота можно убрать, если они не нужны.
17 DIvanmgn
 
12.04.12
09:39
(14) :).. несколько больше.. раз в 100..
18 azernot
 
12.04.12
09:41
(17) 1000 номенклатуры м 10000 документов? Тоже не так много. увеличь ещё в 10-100 раз, тогда увидишь разницу :)
19 DIvanmgn
 
12.04.12
09:43
(16) отбор по группе нужен. Если помечен - то не попадет в документ. Не спорю.. Оборот нельзя убирать - нужны именно те позиции которые участвовали в обороте.
20 DIvanmgn
 
12.04.12
09:43
(18) может с базой какой косяк.. но твой запрос все еще выполняется..
21 azernot
 
12.04.12
09:44
(15) "двигался по определённому складу" - подойдёт абсолютно любое движение? Может быть имеет смысл использовать не вирутальную таблицу оборотов, а реальную таблицу регистра. Даст ещё прирост производительности.
22 DIvanmgn
 
12.04.12
09:46
(21) спасибо за идею попробую
23 Sewace
 
12.04.12
09:46
(12)
Что-то типа вот этого:
ВЫБРАТЬ
  Таб....
ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата, Склад = &Склад и НЕ Номенклатура.ПометкаУдаления и ......) как Таб
24 azernot
 
12.04.12
09:47
ВЫБРАТЬ
   Номенклатура.Ссылка КАК Номенклатура
ПОМЕСТИТЬ СпрНоменклатура
ИЗ
   Справочник.Номенклатура КАК Номенклатура
ГДЕ
   (НЕ Номенклатура.ПометкаУдаления)
   И (НЕ Номенклатура.ЭтоГруппа)
   И Номенклатура.Ссылка В ИЕРАРХИИ(&Группа)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ТоварыНаСкладахОстатки.Номенклатура,
   ТоварыНаСкладахОстатки.КоличествоОстаток
ИЗ
   РегистрНакопления.ТоварыНаСкладах.Остатки(
           &Дата,
           Склад = &Склад
               И Номенклатура В
                   (ВЫБРАТЬ
                       СпрНоменклтура.Номенклатура
                   ИЗ
                       СпрНоменклтура)) КАК ТоварыНаСкладахОстатки
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
           ТоварыНаСкладах.Номенклатура КАК Номенклатура
       ИЗ
           РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
       ГДЕ
           ТоварыНаСкладах.Период МЕЖДУ &Дата1 И &Дата2
           И ТоварыНаСкладах.Склад = &Склад
           И ТоварыНаСкладах.Номенклатура В
                   (ВЫБРАТЬ
                       СпрНоменклатура.Номенклатура
                   ИЗ
                       СпрНоменклатура)) КАК ДвиженияТоваров
       ПО ТоварыНаСкладахОстатки.Номенклатура = ДвиженияТоваров.Номенклатура
25 DIvanmgn
 
12.04.12
09:48
(2) Временные таблицы, индексы, пакетный запрос. И будет тебе счастье.

А куда в (8) можно воткнуть индекс?
26 guitar_player
 
12.04.12
09:49
(0) нет
27 DIvanmgn
 
12.04.12
09:51
(26) :) зачетный пост
28 DimVad
 
12.04.12
09:51
(25) В первом запросе, где получается СпрНоменклатура можно проиндексировать по "Номенклатура". Если номенклатур много, должен дать хороший выигрыш.
29 Нуф-Нуф
 
12.04.12
09:53
вложенные запросы - это гомнокод
30 dmpl
 
12.04.12
09:53
(0) А чем не катит таблица ОстаткиИОбороты?
31 DIvanmgn
 
12.04.12
09:54
(30) правая граница периода оборота и дата среза остатка разные
32 dmpl
 
12.04.12
09:55
(31) И какой в этом смысл?
33 DIvanmgn
 
12.04.12
09:55
(24) вообще махом отработало - только дубли.. попытка применить "РАЗЛИЧНЫЕ" к вложенному запросу привела опять к зависону
34 DimVad
 
12.04.12
09:55
(29) +100 Но лучше выразить вежливее "Вложенные запросы проходилось применять до появления временных таблиц"
35 DIvanmgn
 
12.04.12
09:56
(32) показывает человеку товар, который он раньше продавал (ну или хотя бы возил с места на место) а сейчас этого товара нет
36 DIvanmgn
 
12.04.12
09:57
(23) Где-то слышал что соединение работает быстрее чем отбор
37 fly7
 
12.04.12
09:58
(29) вложенные запросы воще не надо использовать? или есть иногда смысл?
38 azernot
 
12.04.12
10:00
(33) Ну попробуй так... В порядке бреда:

ВЫБРАТЬ
   ТоварыНаСкладахОстатки.Номенклатура,
   ТоварыНаСкладахОстатки.КоличествоОстаток
ИЗ
   РегистрНакопления.ТоварыНаСкладах.Остатки(
           &Дата,
           Склад = &Склад
               И Номенклатура В
                   (ВЫБРАТЬ
                       ТоварыНаСкладах.Номенклатура КАК Номенклатура
                   ИЗ
                       РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
                   ГДЕ
                       ТоварыНаСкладах.Период МЕЖДУ &Дата1 И &Дата2
                       И ТоварыНаСкладах.Склад = &Склад
                       И ТоварыНаСкладах.Номенклатура В
                           (ВЫБРАТЬ
                               Номенклатура.Ссылка
                           ИЗ
                               Справочник.Номенклатура КАК Номенклатура
                           ГДЕ
                               (НЕ Номенклатура.ПометкаУдаления)
                               И (НЕ Номенклатура.ЭтоГруппа)
                               И Номенклатура.Ссылка В ИЕРАРХИИ (&Группа)))) КАК ТоварыНаСкладахОстатки
39 Нуф-Нуф
 
12.04.12
10:00
(37) имхо вообще не стоит
40 dmpl
 
12.04.12
10:00
(35) Ну а остатки-то зачем? Там ведь левое соединение, так что выйдет вся номенклатура (она слева) вне зависимости от того, есть остатки по ней или нет.
41 y88
 
12.04.12
10:01
запрос из РегистрНакопления.ТоварыНаСкладах во временную таблицу + различные
А потом внутреннее соединение с остатками
42 Нуф-Нуф
 
12.04.12
10:01
попробуй нормально отладить запрос со вложенными
43 DIvanmgn
 
12.04.12
10:01
(37) Вот тут много высказались про вложенные запросы. однако вариант (24), используя вложенные запросы показал наивысшую производительность
+ применил совет (28) - вообще взлетело все!
44 ILM
 
гуру
12.04.12
10:01
(0) Дурдом на колесах )))
Зачем там остатки, потом остатки и обороты, почему не взять только из оборотов, условие на номенклатуру тоже можно засунуть в параметры виртуальной таблицы.
А здесь горе от ума какое-то:
Две таблицы Номенклатура и ОстаткиИОбороты и будет счастье...
45 DIvanmgn
 
12.04.12
10:02
В ИТОГЕ (Отрабатывает за пару секунд):

ВЫБРАТЬ
   Номенклатура.Ссылка КАК Номенклатура
ПОМЕСТИТЬ СпрНоменклатура
ИЗ
   Справочник.Номенклатура КАК Номенклатура
ГДЕ
   (НЕ Номенклатура.ПометкаУдаления)
   И (НЕ Номенклатура.ЭтоГруппа)
   И Номенклатура.Ссылка В ИЕРАРХИИ(&Группа)

ИНДЕКСИРОВАТЬ ПО
   Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
   ТоварыНаСкладахОстатки.Номенклатура,
   ТоварыНаСкладахОстатки.КоличествоОстаток
ИЗ
   РегистрНакопления.ТоварыНаСкладах.Остатки(
           &Дата,
           Склад = &Склад
               И Номенклатура В
                   (ВЫБРАТЬ
                       СпрНоменклатура.Номенклатура
                   ИЗ
                       СпрНоменклатура)) КАК ТоварыНаСкладахОстатки
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
           ТоварыНаСкладах.Номенклатура КАК Номенклатура
       ИЗ
           РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
       ГДЕ
           ТоварыНаСкладах.Период МЕЖДУ &Дата1 И &Дата2
           И ТоварыНаСкладах.Склад = &Склад
           И ТоварыНаСкладах.Номенклатура В
                   (ВЫБРАТЬ
                       СпрНоменклатура.Номенклатура
                   ИЗ
                       СпрНоменклатура)) КАК ДвиженияТоваров
       ПО ТоварыНаСкладахОстатки.Номенклатура = ДвиженияТоваров.Номенклатура
46 guitar_player
 
12.04.12
10:02
(39) почему? если нужно просто сделать несколько преобразований текущих данныхперед дальнейшим соединением, это можно сделать в одной временной таблицы с вложенными запросами, а в другой соединиться
47 dmpl
 
12.04.12
10:04
(45) Ну а если на &Дата остатков нужного товара нет, а обороты по нему есть?
48 azernot
 
12.04.12
10:04
(39) Обоснуй. (42) - за обоснование не катит. Консоль запросов в зубы и вперёд.
49 guitar_player
 
12.04.12
10:06
(48) +100500, пофиг как что отлаживать. Конструктором редко пользуюсь
50 azernot
 
12.04.12
10:09
(49) А на коструктор ты зря. Пользуюсь всегда. Даже если что-то редактирую руками, апосля конструктором форматирую.
51 dk
 
12.04.12
10:11
можно во временную сразу затащить данные из РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
должно еще пошустрее быть
52 azernot
 
12.04.12
10:14
Может я крамольную мысль скажу, но я всегда считал, что Временная таблица нужна в том случае, если её результат я собираюсь использовать несколько раз (более одного). В остальных случаях она не лучше и не хуже обычного вложенного запроса. Я не прав?
53 DimVad
 
12.04.12
10:15
(48) Временные таблицы фирма 1С сделала именно для замены вложенных запросов. Причин несколько. Навскидку:

1. Гораздо менее требовательны к ресурсам (уход от вылетов из-за нехватки памяти, например).

2. Позволяет выполнять оптимизацию (врем. таб. можно индексировать, например).

3. Код становится "плоским". Т.е. видно - вот этот запрос выполняет отдельное действие и помещает в врем. таблицу. И из-за этого потом переделывать весь запрос становится легче. Читать его легче. Это и называется "легче отлаживать".

Я, конечно, понимаю - есть люди, к-рые скажут : "А я уже миллион лет пользуюсь вл. зап. и так навострился это делать"... Но это ущербная логика. Вот я когда-то был очень не хилым спецов по Clipper, и что теперь ? Всю жизнь на нем писать ?
54 DimVad
 
12.04.12
10:16
(52) Я свидетель - имел вылеты по памяти, когда вложенный запрос использовался ровно один раз. После перехода на ВТ вылеты пропали и возросла скорость...
55 guitar_player
 
12.04.12
10:16
(52) не прав. Вложенные таблицы не содержат индекса. При соединении может быть не оптимально выбран план выполнения запроса. Плюс есть тема, что оптимизатор не считает количество записей во вложенной таблице, что тоже сказывается на план выполнения запроса
56 guitar_player
 
12.04.12
10:17
(53) Вообще от вложенных таблиц в принципе можно отказаться...
Здесь можно обсудить любую тему при этом оставаясь на форуме для 1Сников, который нужен для работы. Ymryn