Вход | Регистрация
 

Не хочу запрос в цикле, а оно заставляет

Не хочу запрос в цикле, а оно заставляет
Я
   RomaH
 
02.03.21 - 09:09
Запрос = Новый Запрос;
    
    Запрос.УстановитьПараметр("ТипДокумента",ИдентификаторДокумента);
    Запрос.УстановитьПараметр("ИмяПоля",ИмяРеквизита);
    
    Запрос.Текст =
    "ВЫБРАТЬ
    |    ЗначенияДляПодстановок.Значение КАК ТекстСписка,
    |    ЗначенияДляПодстановок.Количество КАК КоличествоУпоминаний
    |ИЗ
    |    РегистрСведений.ЗначенияДляПодстановок КАК ЗначенияДляПодстановок
    |ГДЕ
    |    ЗначенияДляПодстановок.ТипДокумента = &ТипДокумента
    |    И ЗначенияДляПодстановок.ИмяПоля = &ИмяПоля
    |
    |УПОРЯДОЧИТЬ ПО
    |    КоличествоУпоминаний УБЫВ";

вот такой запрос выполняю 25 раз за 1.2 секунды

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


1 раз, но 2.2 секунды

    "ВЫБРАТЬ
    |    ЗначенияДляПодстановок.Значение КАК ТекстСписка,
    |    ЗначенияДляПодстановок.Количество КАК КоличествоУпоминаний
    |ИЗ
    |    РегистрСведений.ЗначенияДляПодстановок КАК ЗначенияДляПодстановок
    |ГДЕ
    |    ЗначенияДляПодстановок.ТипДокумента = &ТипДокумента
    |    И ЗначенияДляПодстановок.ИмяПоля = &ИмяПоля0
    | ОБЪЕДИНИТЬ ВСЕ
    |ВЫБРАТЬ
    |    ЗначенияДляПодстановок.Значение КАК ТекстСписка,
    |    ЗначенияДляПодстановок.Количество КАК КоличествоУпоминаний
    |ИЗ
    |    РегистрСведений.ЗначенияДляПодстановок КАК ЗначенияДляПодстановок
    |ГДЕ
    |    ЗначенияДляПодстановок.ТипДокумента = &ТипДокумента
    |    И ЗначенияДляПодстановок.ИмяПоля = &ИмяПоля1 ...
    |

такой - 3.5 секунды

регистр с текстовыми полями
ИмяПоля - Строка 150

ТипДокумента  -  составной - Строка + Справочник.ИдентификаторыОбъектовМД
   ДенисЧ
 
1 - 02.03.21 - 09:12
"Не держитесь устава, яко слепой стены;
в нем бо порядки писаны, а времен и случаев нет".

(с) Александр Васильевич
   BeerHelpsMeWin
 
2 - 02.03.21 - 09:15
(0) >"Не хочу запрос в цикле, а оно заставляет"
ты так говоришь, как будто это что-то плохое...
   acht
 
3 - 02.03.21 - 09:29
(0) Каие измерения и в каком они порядке у регистра?
   arsik
 
4 - 02.03.21 - 09:34
(0) ТипДокумента индексированный?
Может сначала по типу документа во временную, а потом на временную наложить фильтр по массиву имен полей.
   arsik
 
5 - 02.03.21 - 09:36
Ну и еще сначала попробовать статистику на скуле обновить
   mistеr
 
6 - 02.03.21 - 09:41
(0) 1.3 сек. разницы это недостаточное искушение. Не поддавайся.
   Почему 1С
 
7 - 02.03.21 - 09:42
Третий запрос  = Первый запрос в цикле , но без доп. соединений к базе
Запросы в цикле тут не нужен
Я бы делал второй запрос
   brainguard
 
8 - 02.03.21 - 09:49
Ни в коем случае не пиши запросы в цикле! Программистом станешь
   VS-1976
 
9 - 02.03.21 - 10:55
Нужно попробовать тогда такой запрос, что бы всё уже измерить )

ВЫБРАТЬ
    ЗначенияДляПодстановок.Значение КАК ТекстСписка,
    ЗначенияДляПодстановок.Количество КАК КоличествоУпоминаний
ИЗ
    ( ВЫБРАТЬ "ИмяПоля1" КАК ИмяПоля
      ОБЪЕДИНИТЬ ВСЕ
      ВЫБРАТЬ "ИмяПоляN"
    ) КАК тзИменаПолей

    СОЕДИНЕНИЕ РегистрСведений.ЗначенияДляПодстановок КАК ЗначенияДляПодстановок
    ПО ЗначенияДляПодстановок.ТипДокумента = &ТипДокумента
         И ЗначенияДляПодстановок.ИмяПоля = тзИменаПолей.ИмяПоля

УПОРЯДОЧИТЬ ПО
   КоличествоУпоминаний УБЫВ
   VS-1976
 
10 - 02.03.21 - 10:58
(9) Либо имена полей завести через ТаблицаЗначений, с правильным описанием типа поля, на сколько я понимаю строка( непонятная длина )
Или ВЫБРАТЬ ВЫРАЗИТЬ( "ИмяПоля1" КАК СТРОКА( [Длина строки] ) ) КАК ИмяПоля
   RomaH
 
11 - 02.03.21 - 11:33
(6) 1.3 секунды - это в 2 раза больше на тестовом сервере
на рабочем может быть и 5 секунд

и это при открытии формы - очень не комфортно
(9), (10) - спасибо - посмотрю
   fisher
 
12 - 02.03.21 - 13:59
Как уже советовали - первым делом обновить статистику.
Сделай EXEC sp_updatestats
Оно и кэши планов выполнения сбрасывает, так что сразу увидишь есть эффект или нет.
Если нет эффекта, то любопытно было бы запрофайлить планы выполнения, чтобы понять почему проседание.
   Гений 1С
 
13 - 02.03.21 - 14:10
(0) запрет запросов в цикле - это религия, не верь в дурное
   vi0
 
14 - 02.03.21 - 14:24
"иногда требуемое условие запроса, позволяющее отказаться от выполнения в цикле, сформулировать бывает затруднительно или очень сложно. В этом случае как минимум нужно вынести создание запроса за пределы цикла, а в цикле изменять только параметры запроса. Это позволит избежать многократной синтаксической проверки текста запроса"
https://its.1c.ru/db/pubqlang/content/150/hdoc
   VS-1976
 
15 - 02.03.21 - 14:59
(14) Если данные нужно не сразу, то можно и после открытия формы получить их, к примеру в фоновом задании
   ДедМорроз
 
16 - 02.03.21 - 15:19
Как бы,не стоит бояться запроса в цикле,если он по индексу,так как несколько поисков по этому индексу или все равно будут запросы в цикле или исключение индекса.
   RomaH
 
17 - 02.03.21 - 15:32
ну как бы есть нормы и правила, -
Не использовать запросы в цикле - из https://its.1c.ru/db/pubqlang/content/150/hdoc

по сути, был бы не ленивым - сразу написал бы что-то вроде второго варианта из (0), и даже мысли бы не было переписать на цикл

а тут вон как...
   H A D G E H O G s
 
18 - 02.03.21 - 15:40
(16) Запрос в цикле и цикл в запросе - это краааайне разные вещи.
   ДедМорроз
 
19 - 02.03.21 - 15:56
(18) в нормальном sql без разницы.
Не забываем,что любой запрос,это цикл движения курсора,а вот где он движется,это уже другой вопрос.
Понятно,что сканирование индекса по списку можно делать,предварительно упорядочив список,но не всякий индекс позволяет продолжить сканирование из середины также эффективно,как сначала.
   ДедМорроз
 
20 - 02.03.21 - 15:58
Например,как соединить две таблицы
Проще из упорядочить и по ленточке пробежать,а можно в лоб,для каждой строки одной делать поиск по другой.
И тут все зависит от объема данных.
   H A D G E H O G s
 
21 - 02.03.21 - 16:26
(19) А причем тут SQL, если запрос выплняется из 1С? Вот задержки на отправку запроса и получение ответа - и есть основные затраты на запрос в цикле.
   H A D G E H O G s
 
22 - 02.03.21 - 16:28
"Понятно,что сканирование индекса по списку можно делать,предварительно упорядочив список,но не всякий индекс позволяет продолжить сканирование из середины также эффективно,как сначала."

пшшшш, набор букав.
   H A D G E H O G s
 
23 - 02.03.21 - 16:31
(21) ну и подобрать план запроса по статистике, но я думаю, там все быстрее.
   vi0
 
24 - 02.03.21 - 16:45
(21) т.е. работа sql в сумме будет та же, а накладные расходы чисто на 1с?
не замерял, но верится слабо
   Said_We
 
25 - 03.03.21 - 17:14
(0) Во втором запросе где параметр "И ЗначенияДляПодстановок.ИмяПоля В (&МассивИмемПолей)" устанавливается не увидел.
ИмяПоля - строка 150, у у вида документа какая разрядность?
Эти поля измерения? Индексы есть по этим полям?
Зачем такая большая разрядность для текстового поля с именем?
   Said_We
 
26 - 03.03.21 - 17:16
Первый запрос выполняешь 25 раз - параметры одни и те же или меняешь перед вызовом запроса? Так на всякий случай спрошу.
   ДедМорроз
 
27 - 03.03.21 - 22:44
Накладные расходы на передачу данных не так существенны,как построение плана запроса.
Для исключения повторного построения плана в sql есть специальная конструкция prepare-execute,да и в 1с,если создать запрос один раз,а потом только менять параметры,то повторной трансляции быть не должно.
Конечно,если sql отдельно,то передача запроса по сети и получение ответа тоже занимает время,но его можно учитывать,когда таблицы маленькие и сама выборка по ним занимает время меньшее,чем прочие действия.
   Волшебник
 
28 - 03.03.21 - 23:03
У профессионалов запросы в циклах не тормозят!
   assasu
 
29 - 04.03.21 - 05:31
(0) запрос в цикле писать можно. Если количество итераций цикла зависит от программиста, а не от действий пользователя.
   RomaH
 
30 - 04.03.21 - 07:04
(25) документ - ссылка
разрядность - что бы было .... м.б ИмяТабличногоПоля.ИмяХитровыдуманногоРеквизита
в измерениях все три
не индексированы - добавление индекса добавляет время выполнения запроса
параметр естественно меняю (имя поля)
МассивИменПолей - это Массив имен полей - т.е. строк
 
 Рекламное место пустует
   Said_We
 
31 - 04.03.21 - 11:46
Индекс по строкам 150 - это многовато. Какая максимальная длина которая содержится по факту в регистре в поле "ИмяПоля"?
   Said_We
 
32 - 04.03.21 - 11:48
В каком порядке идут измерения в регистре? Сколько измерений и какие типы с размерностью?
   RomaH
 
33 - 04.03.21 - 11:58
(32)
https://ibb.co/sRcvdTW

макс длина сейчас 62
третье измерение - строка 200
   Said_We
 
34 - 04.03.21 - 12:07
Составных типов нет?
   Said_We
 
35 - 04.03.21 - 12:12
Судя по переписке выше есть....
"ТипДокумента  -  составной - Строка + Справочник.ИдентификаторыОбъектовМД"
Строка сколько?
   Said_We
 
36 - 04.03.21 - 12:14
"макс длина сейчас 62" - т.е. со 150 смело можно уменьшить до 100.
   Said_We
 
37 - 04.03.21 - 12:15
На сколько целесообразно использовать составной тип в измерении "ТипДокумента"? Строка сейчас используется хоть в одном случае?
   RomaH
 
38 - 04.03.21 - 13:24
(35) убрал уже
... мне интересен сам факт, и почему вот так происходит

код уже оптимизирован в 10 раз, там без цикла не получилось бы - мне еще только несколько первых записей надо

добавил Первые 10, получил выгрыш по времени в 10 раз
   Вафель
 
39 - 04.03.21 - 13:36
начнем с того что запрос 1 и 2 не эквиваленты.
в 2 запросе еще нужно имя поля
   Вафель
 
40 - 04.03.21 - 13:37
и по факту нормально 1 запрос во 2 не переделаешь
   youalex
 
41 - 04.03.21 - 13:39
(38) в профайлере посмотри какие запросы генерятся.
есть подозрение что условие ЗначенияДляПодстановок.ИмяПоля В (&МассивИмемПолей) порождает неявное создание ВТ по этому массиву.
   H A D G E H O G s
 
42 - 04.03.21 - 14:33
Давно бы уже на план запроса посмотрели бы и не гадали.
   toypaul
 
43 - 04.03.21 - 15:57
Разница в секунду абсолютно ничтожна. Вот когда записей количество отборов сотни тысяч и в итоге В может выполняться пол дня, а 100 тыс раз за пару минут - вот это да.

Это называется криворукие разработчики МС СКЛ. Этой проблеме хренова туча лет, а они все еще не умеют разбивать список ИЛИ на несколько запросов. Ну или я не знаю - написать человеческий оптимизатор. Сколько уже можно обмусоливать эту проблему?
   H A D G E H O G s
 
44 - 04.03.21 - 16:13
(43) Это называется некомпетентность. Ваша.
   ViSo76
 
45 - 04.03.21 - 16:30
(33) Имя поля может сделать справочником?
А что за задача такая, что такой регистр пришлось делать?
   toypaul
 
46 - 04.03.21 - 17:02
(44) ты я так понимаю любишь всякими извращениями заниматься, да? вместо того чтобы написать в запрос Поле В (&Список), выполнить сотню таких запросов.

очень же приятно таращить свою компетентность в таких извращениях. нормальный инструмент не должен заставлять разработчика такой фигней страдать. нормальный инструмент сам должен внтури себя разбить это на 100 запросов. если об этом известно уже с десяток лет.

ну нет. нам же нужны специалисты по оптимизации, которые будут надувать губы ... у ... да у вас тут несколько ИЛИ и условие по списку.
   Вафель
 
47 - 04.03.21 - 17:29
смысл страдать всей этой х..ней, если 2 запрос вообще не решает изначальную задачу?
   H A D G E H O G s
 
48 - 04.03.21 - 18:44
(46) Выдыхайте. Поле В (&Список) нормально отрабатывается SQL-ем
   Исновая
 
49 - 04.03.21 - 18:52
Зачем цикл? Пользуй рекурсию
   ДедМорроз
 
51 - 05.03.21 - 23:28
Запрос с В при большом количестве элементов в может исполняться как соединение,но перед этим список упорядочивается,тогда время выполнения не будет большим.
Если же в лоб,то оптимизатор sql будет выполнять сканирование по индексу с поиском в массиве,а поиск в массиве - это его перебор.
   Said_We
 
52 - 09.03.21 - 10:50
(38) По строкам большой длины поиск идет не быстро. Максимально сократи размерность. Например до строка(100) или строка(80)
Вместо "ЗначенияДляПодстановок.ИмяПоля В (&МассивИмемПолей)"
Можно попробовать как-то так: ЗначенияДляПодстановок.ИмяПоля В (выбрать т.ИмяПоля из ВТ_МассивИмемПолей как т)
ВТ_МассивИмемПолей предварительно создать и проиндексировать по "ИмяПоля".
Пробуй.
   Said_We
 
53 - 10.03.21 - 12:30
(0) Попробовал?
   Said_We
 
54 - 10.03.21 - 12:50
(38) "Первые 10" всегда быстрее чем полная выборка, в которой много записей. Чем больше записей в полной выборке, тем больше разница во времени. "Первые 1" быстрее чем "Первые 10", но увидеть это иногда можно только в миллисекундах. Почему иногда? Потому что "Первые ХХХ" может относится не к итоговой выборке.
   H A D G E H O G s
 
55 - 10.03.21 - 12:57
(54) Первые 10 останавливают скан, как только нашли Первые 10. Которые могли быть рядом, просто из за пропуска предиката поиска. Ваш КЭП.
   Said_We
 
56 - 10.03.21 - 15:33
(55) Это, наверное, не мне, а ответ (38).
   Said_We
 
57 - 11.03.21 - 15:13
Не интересно уже (0) пробовать что либо. :-)


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