Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Оптимизация кода с запросом.

Оптимизация кода с запросом.
Я
   JuixyJes
 
30.07.19 - 15:41
Запрос = Новый Запрос;
     Запрос.Текст =
     "ВЫБРАТЬ
     |    ЗагруженностьНФ.НомерПроживания КАК НомерПроживания,
     |    ЗагруженностьНФ.КомнатаПроживания КАК КомнатаПроживания,
     |    ЗагруженностьНФ.КойкаПроживания КАК КойкаПроживания,
     |    ЗагруженностьНФ.ДатаЗаселения КАК ДатаЗаселения,
     |    ЗагруженностьНФ.ДатаВыезда КАК ДатаВыезда,
     |    ЗагруженностьНФ.Регистратор КАК Регистратор
     |ИЗ
     |    РегистрСведений.ЗагруженностьНФ КАК ЗагруженностьНФ
     |ГДЕ
     |    ЗагруженностьНФ.НомерПроживания = &НомерПроживания
     |    И ЗагруженностьНФ.КомнатаПроживания = &КомнатаПроживания
     |    И ЗагруженностьНФ.КойкаПроживания = &КойкаПроживания
     |
     |УПОРЯДОЧИТЬ ПО
     |    ДатаЗаселения,
     |    ДатаВыезда";
     Запрос.УстановитьПараметр("НомерПроживания", Объект.НомерПроживания);
     Запрос.УстановитьПараметр("КомнатаПроживания", Справочники.Комнаты.ПустаяСсылка());
     Запрос.УстановитьПараметр("КойкаПроживания", Справочники.Койки.ПустаяСсылка());
    
     РезультатЗапроса = Запрос.Выполнить();
    
     ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
     СЗ = Новый ТаблицаЗначений;
     СЗ.Колонки.Добавить("Регистратор");
     СЗ.Колонки.Добавить("ДатаНачала");
     СЗ.Колонки.Добавить("ДатаОкончания");
     Если не РезультатЗапроса.Пустой() Тогда
         Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
             НСТР = СЗ.Добавить();
             НСТР.Регистратор = ВыборкаДетальныеЗаписи.Регистратор;
             НСТР.ДатаНачала = ВыборкаДетальныеЗаписи.ДатаЗаселения;
             НСТР.ДатаОкончания = ВыборкаДетальныеЗаписи.ДатаВыезда ;
         КонецЦикла;
     Иначе
         Запрос.УстановитьПараметр("НомерПроживания", Объект.НомерПроживания);
         Запрос.УстановитьПараметр("КомнатаПроживания", Объект.КомнатаПроживания);
         Запрос.УстановитьПараметр("КойкаПроживания", Справочники.Койки.ПустаяСсылка());
         РЗ = Запрос.Выполнить();
         Выб = Рз.Выбрать();
         Если не РЗ.Пустой() Тогда
             Пока Выб.Следующий() Цикл
                 НСТР = СЗ.Добавить();
                 НСТР.Регистратор = Выб.Регистратор;
                 НСТР.ДатаНачала = Выб.ДатаЗаселения;
                 НСТР.ДатаОкончания = Выб.ДатаВыезда ;
             КонецЦикла;
         Иначе
             Запрос.УстановитьПараметр("НомерПроживания", Объект.НомерПроживания);
             Запрос.УстановитьПараметр("КомнатаПроживания", Объект.КомнатаПроживания);
             Запрос.УстановитьПараметр("КойкаПроживания", Объект.КойкаПроживания);
             РЗ = Запрос.Выполнить().Выбрать();
             Пока РЗ.Следующий() Цикл
                 НСТР = СЗ.Добавить();
                 НСТР.Регистратор = РЗ.Регистратор;
                 НСТР.ДатаНачала = РЗ.ДатаЗаселения;
                 НСТР.ДатаОкончания = РЗ.ДатаВыезда ;
             КонецЦикла;
         КонецЕсли;
     КонецЕсли;
     Возврат СЗ;
 
 
   JuixyJes
 
1 - 30.07.19 - 15:42
Знаю что не оптимально. Но можно ж как то оптимизировать сие творение. Ибо 3 раза запрос выполнять не очень, выполняется аж 6.5 секунды, что неприемлемо:\
   unregistered
 
2 - 30.07.19 - 15:49
Это дичь какая-то в любом случае.
Но правильный ответ зависит от задачи. Что конкретно нужно получить? Я, например, вообще ничего не понял из этого текста. Очень похоже на кривую изначальную архитектуру, чью косячность пытаются обходить такими дикими заплатами.
   JuixyJes
 
3 - 30.07.19 - 15:53
(2) Нууу, есть 3 реквизита. Номер, комната, койка. Если есть записи, где заполнен только номер, то нужно их в СЗ(ТЗ) добавить, если таких записей нет, то найти записи где заполнены номер и комната и по аналогии их добавить в СЗ(ТЗ), если и таких записей нет, то найти записи, где заполнены все 3 реквизита. Как то так
   Йохохо
 
4 - 30.07.19 - 15:54
6.5 секунд не может быть + вероятно РегистрСведений.ЗагруженностьНФ периодический и надо срез брать
   JuixyJes
 
5 - 30.07.19 - 15:55
(4) Да, периодический. А если он будет не периодический, возможно, что он будет быстрее отрабатывать?
   Йохохо
 
6 - 30.07.19 - 15:55
(5) если взять срез он будет быстрее
   Йохохо
 
7 - 30.07.19 - 15:58
но для 6.5 секунд база должна быть в работе лет 5) если меньше структура регистра белая лиса
   novichok79
 
8 - 30.07.19 - 15:58
дичь какая-то, ну мои 3 копейки, дальше сама

    Запрос = Новый Запрос; 
    Запрос.Текст = 
    "ВЫБРАТЬ
    |    Т.НомерПроживания КАК НомерПроживания,
    |    Т.КомнатаПроживания КАК КомнатаПроживания,
    |    Т.КойкаПроживания КАК КойкаПроживания,
    |    Т.ДатаЗаселения КАК ДатаЗаселения,
    |    Т.ДатаВыезда КАК ДатаВыезда,
    |    Т.Регистратор КАК Регистратор,
    |    ВЫБОР
    |        КОГДА Т.КомнатаПроживания В (ЗНАЧЕНИЕ(Справочник.Комнаты.ПустаяСсылка))
    |                И Т.КойкаПроживания В (ЗНАЧЕНИЕ(Справочник.Койки.ПустаяСсылка))
    |            ТОГДА 1
    |        КОГДА Т.КомнатаПроживания В (&КомнатаПроживания)
    |                И Т.КойкаПроживания В (ЗНАЧЕНИЕ(Справочник.Койки.ПустаяСсылка))
    |            ТОГДА 2
    |        КОГДА Т.КомнатаПроживания В (&КомнатаПроживания)
    |                И Т.КойкаПроживания В (&КойкаПроживания)
    |            ТОГДА 3
    |        ИНАЧЕ 0
    |    КОНЕЦ КАК Приоритет
    |ИЗ
    |    РегистрСведений.ЗагруженностьНФ КАК Т
    |ГДЕ
    |    Т.НомерПроживания = &НомерПроживания
    |    И Т.КомнатаПроживания В (ЗНАЧЕНИЕ(Справочник.Комнаты.ПустаяСсылка), &КомнатаПроживания)
    |    И Т.КойкаПроживания В (ЗНАЧЕНИЕ(Справочник.Койки.ПустаяСсылка), &КойкаПроживания)
    |
    |УПОРЯДОЧИТЬ ПО
    |    Приоритет,
    |    ДатаЗаселения,
    |    ДатаВыезда
    |ИТОГИ
    |    КОЛИЧЕСТВО(Регистратор)
    |ПО
    |    Приоритет"; 
    
    Запрос.УстановитьПараметр("НомерПроживания", Объект.НомерПроживания); 
    Запрос.УстановитьПараметр("КомнатаПроживания", Объект.КомнатаПроживания); 
    Запрос.УстановитьПараметр("КойкаПроживания", Объект.КойкаПроживания); 

    РезультатЗапроса = Запрос.Выполнить();
    
    ВыборкаПриоритет = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
    
    Пока ВыборкаПриоритет.Следующий() Цикл
        // Вставить обработку выборки ВыборкаПриоритет

        
        ВыборкаДетальныеЗаписи = ВыборкаПриоритет.Выбрать();
        
        Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
            // Вставить обработку выборки ВыборкаДетальныеЗаписи

        КонецЦикла;
        
    КонецЦикла;
   novichok79
 
9 - 30.07.19 - 15:59
(2) +100500
   ptiz
 
10 - 30.07.19 - 15:59
(1) Включи "Индексировать" в регистре на поле ЗагруженностьНФ и сравни как изменится время выполнения.
   unregistered
 
11 - 30.07.19 - 16:00
(3) Это я понял. Не совсем же я дурак. Я в упор не могу понять для чего этот бред может понадобиться. Для какой конкретной задачи.
   lodger
 
12 - 30.07.19 - 16:04
(11) у госпитальеров свои думные думки, какая тебе разница?
модифицировать (8) на СрезПоследних.
   unregistered
 
13 - 30.07.19 - 16:06
(8) Только так как нам нужен только вариант с одним приоритетом, то заменить цикл на условие.

 Пока ВыборкаПриоритет.Следующий() Цикл
  // Вставить обработку выборки ВыборкаПриоритет

 КонецЦикла;

на
 Если ВыборкаПриоритет.Следующий() Тогда
  // Вставить обработку выборки ВыборкаПриоритет

 КонецЕсли;
   novichok79
 
14 - 30.07.19 - 16:06
(12) да ради бога.
   Йохохо
 
15 - 30.07.19 - 16:07
берем срез и пишем 
выбор когда ЗагруженностьНФ.КомнатаПроживания <> Значение(Справочник.КомнатыПроживания.ПустаяСсылка) Тогда ЗагруженностьНФ.ДатаЗаселения Иначе ДАТАВРЕМЯ(1,1,1) конец КАК ДатаНачала
   ptiz
 
16 - 30.07.19 - 16:07
(0) Вообще, логика странная: обычно сначала ищут точное совпадение, а затем смягчают поиск, а тут наоборот.

Если надо красиво, то делаем так:
- создаем табличку ТЗОтбор из 3х строк:
Номер, Комната, Койка, Приоритет
-------------------
Объект.Номер, пусто, пусто, 1
Объект.Номер, Объект.Комната, пусто, 2
Объект.Номер, Объект.Комната, Объект.Койка, 3

Пихаем в запрос во временную таблицу и соединяем с РС, сортируем по "Приоритет", делает ИТОГ по Приоритет, чтобы первым заходом выбрать нужное.

Но эффект зависит от данных: как много пустых значений в РС, как много разных значений в РС.
   novichok79
 
17 - 30.07.19 - 16:07
(13) а это уже Елизавете самой подумать надо ))
   Йохохо
 
18 - 30.07.19 - 16:08
второе и третье условие в топку
   vicof
 
19 - 30.07.19 - 16:08
(0) Убрать километры кода, сделать запрос только с отбором по номеру и чуть усложнить отборы по комнатам и койкам на пустое значение.
   unregistered
 
20 - 30.07.19 - 16:09
(12) С чего ты взял, что это периодический регистр?...
   JuixyJes
 
21 - 30.07.19 - 16:10
(8) Вооот я хотела условия в запрос вставить. Нооо, я не так давно этим всем занимаюсь и условия в запрос еще не ставила никогда. А дальше мне нужно добавить в ТЗ запись если есть в выборке приоритет 1, да?
   PiotrLoginov
 
22 - 30.07.19 - 16:11
(11) ну почему же бред. Попробую перефразировать задачу: для каждой койки, находящейся в Комнате Номера, необходимо получить из регистра запись (СРЕЗ) с некой информацией, касающейся этой койки. Вот и все.

Дело осложняется лишь тем, что если для какой-то койки подходящей записи нет, берем запись для Комнаты, в которой эта койка стоит. А если и для комнаты подходящей записи нет, берем запись для всего номера (реквизиты Комната и Койка не заполнены)


(20) см (5)
   sqr4
 
23 - 30.07.19 - 16:11
(21) ytn
   JuixyJes
 
24 - 30.07.19 - 16:14
(21) Так,  я кажется разобралась.
   sqr4
 
25 - 30.07.19 - 16:16
Формулировку задачки в студию
   sqr4
 
26 - 30.07.19 - 16:16
(24) Главное слово кажется
   Йохохо
 
27 - 30.07.19 - 16:20
(24) что если оставить одно условие и взять срез то весь хвост превратится в Запрос.Выполнить().Выгрузить() ?))))))))
   novichok79
 
28 - 30.07.19 - 16:22
(27) да, кстати, можно максимум по приоритету выбрать, потом записи с таким приоритетом и выгрузить в ТЗ.
   sqr4
 
29 - 30.07.19 - 16:26
нахера нужны записи за 2000 год в 2019?
   Йохохо
 
30 - 30.07.19 - 16:27
(28) см (5), не надо ничего
 
 Рекламное место пустует
   JuixyJes
 
31 - 30.07.19 - 16:41
хммм, вроде бы сам запрос отрабатывает быстро, а вот толи вызов функции то ли фиг его знает что.
   JuixyJes
 
32 - 30.07.19 - 16:41
тупит сильно.
   H A D G E H O G s
 
33 - 30.07.19 - 16:43
Серверный вызов из управляемой формы
   novichok79
 
34 - 30.07.19 - 16:45
(32) возвращай результат запроса в функции с директивой НаСервереБезКонтекста.
но если данных много будет - все равно будет притормаживать на моменте передачи данных между сервером и клиентом.
   hhhh
 
35 - 30.07.19 - 17:23
(31) вот тут чего-то какая-то хрень
        Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
             НСТР = СЗ.Добавить();
             НСТР.Регистратор = ВыборкаДетальныеЗаписи.Регистратор;
             НСТР.ДатаНачала = ВыборкаДетальныеЗаписи.ДатаЗаселения;
             НСТР.ДатаОкончания = ВыборкаДетальныеЗаписи.ДатаВыезда ;
         КонецЦикла; 

пиши так

СЗ = Запрос.ВЫполнить().ВЫгрузить();

ну и соответственно

 |    ЗагруженностьНФ.ДатаЗаселения КАК ДатаНачала,
     |    ЗагруженностьНФ.ДатаВыезда КАК ДатаОкончания,
     |    ЗагруженностьНФ.Регистратор КАК Регистратор


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.