|
Не хочу запрос в цикле, а оно заставляет | ☑ | ||
---|---|---|---|---|
0
RomaH
naïve
02.03.21
✎
09:09
|
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ТипДокумента",ИдентификаторДокумента); Запрос.УстановитьПараметр("ИмяПоля",ИмяРеквизита); Запрос.Текст = "ВЫБРАТЬ | ЗначенияДляПодстановок.Значение КАК ТекстСписка, | ЗначенияДляПодстановок.Количество КАК КоличествоУпоминаний |ИЗ | РегистрСведений.ЗначенияДляПодстановок КАК ЗначенияДляПодстановок |ГДЕ | ЗначенияДляПодстановок.ТипДокумента = &ТипДокумента | И ЗначенияДляПодстановок.ИмяПоля = &ИмяПоля | |УПОРЯДОЧИТЬ ПО | КоличествоУпоминаний УБЫВ"; вот такой запрос выполняю 25 раз за 1.2 секунды Запрос = Новый Запрос; Запрос.УстановитьПараметр("ТипДокумента",ИдентификаторДокумента); Запрос.УстановитьПараметр("ИмяПоля",ИмяРеквизита); Запрос.Текст = "ВЫБРАТЬ | ЗначенияДляПодстановок.Значение КАК ТекстСписка, | ЗначенияДляПодстановок.Количество КАК КоличествоУпоминаний |ИЗ | РегистрСведений.ЗначенияДляПодстановок КАК ЗначенияДляПодстановок |ГДЕ | ЗначенияДляПодстановок.ТипДокумента = &ТипДокумента | И ЗначенияДляПодстановок.ИмяПоля В (&МассивИмемПолей) | |УПОРЯДОЧИТЬ ПО | КоличествоУпоминаний УБЫВ"; 1 раз, но 2.2 секунды "ВЫБРАТЬ | ЗначенияДляПодстановок.Значение КАК ТекстСписка, | ЗначенияДляПодстановок.Количество КАК КоличествоУпоминаний |ИЗ | РегистрСведений.ЗначенияДляПодстановок КАК ЗначенияДляПодстановок |ГДЕ | ЗначенияДляПодстановок.ТипДокумента = &ТипДокумента | И ЗначенияДляПодстановок.ИмяПоля = &ИмяПоля0 | ОБЪЕДИНИТЬ ВСЕ |ВЫБРАТЬ | ЗначенияДляПодстановок.Значение КАК ТекстСписка, | ЗначенияДляПодстановок.Количество КАК КоличествоУпоминаний |ИЗ | РегистрСведений.ЗначенияДляПодстановок КАК ЗначенияДляПодстановок |ГДЕ | ЗначенияДляПодстановок.ТипДокумента = &ТипДокумента | И ЗначенияДляПодстановок.ИмяПоля = &ИмяПоля1 ... | такой - 3.5 секунды регистр с текстовыми полями ИмяПоля - Строка 150 ТипДокумента - составной - Строка + Справочник.ИдентификаторыОбъектовМД |
|||
1
ДенисЧ
02.03.21
✎
09:12
|
"Не держитесь устава, яко слепой стены;
в нем бо порядки писаны, а времен и случаев нет". (с) Александр Васильевич |
|||
2
BeerHelpsMeWin
02.03.21
✎
09:15
|
(0) >"Не хочу запрос в цикле, а оно заставляет"
ты так говоришь, как будто это что-то плохое... |
|||
3
acht
02.03.21
✎
09:29
|
(0) Каие измерения и в каком они порядке у регистра?
|
|||
4
arsik
гуру
02.03.21
✎
09:34
|
(0) ТипДокумента индексированный?
Может сначала по типу документа во временную, а потом на временную наложить фильтр по массиву имен полей. |
|||
5
arsik
гуру
02.03.21
✎
09:36
|
Ну и еще сначала попробовать статистику на скуле обновить
|
|||
6
mistеr
02.03.21
✎
09:41
|
(0) 1.3 сек. разницы это недостаточное искушение. Не поддавайся.
|
|||
7
Почему 1С
02.03.21
✎
09:42
|
Третий запрос = Первый запрос в цикле , но без доп. соединений к базе
Запросы в цикле тут не нужен Я бы делал второй запрос |
|||
8
brainguard
02.03.21
✎
09:49
|
Ни в коем случае не пиши запросы в цикле! Программистом станешь
|
|||
9
VS-1976
02.03.21
✎
10:55
|
Нужно попробовать тогда такой запрос, что бы всё уже измерить )
ВЫБРАТЬ ЗначенияДляПодстановок.Значение КАК ТекстСписка, ЗначенияДляПодстановок.Количество КАК КоличествоУпоминаний ИЗ ( ВЫБРАТЬ "ИмяПоля1" КАК ИмяПоля ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ "ИмяПоляN" ) КАК тзИменаПолей СОЕДИНЕНИЕ РегистрСведений.ЗначенияДляПодстановок КАК ЗначенияДляПодстановок ПО ЗначенияДляПодстановок.ТипДокумента = &ТипДокумента И ЗначенияДляПодстановок.ИмяПоля = тзИменаПолей.ИмяПоля УПОРЯДОЧИТЬ ПО КоличествоУпоминаний УБЫВ |
|||
10
VS-1976
02.03.21
✎
10:58
|
(9) Либо имена полей завести через ТаблицаЗначений, с правильным описанием типа поля, на сколько я понимаю строка( непонятная длина )
Или ВЫБРАТЬ ВЫРАЗИТЬ( "ИмяПоля1" КАК СТРОКА( [Длина строки] ) ) КАК ИмяПоля |
|||
11
RomaH
naïve
02.03.21
✎
11:33
|
(6) 1.3 секунды - это в 2 раза больше на тестовом сервере
на рабочем может быть и 5 секунд и это при открытии формы - очень не комфортно (9), (10) - спасибо - посмотрю |
|||
12
fisher
02.03.21
✎
13:59
|
Как уже советовали - первым делом обновить статистику.
Сделай EXEC sp_updatestats Оно и кэши планов выполнения сбрасывает, так что сразу увидишь есть эффект или нет. Если нет эффекта, то любопытно было бы запрофайлить планы выполнения, чтобы понять почему проседание. |
|||
13
Гений 1С
гуру
02.03.21
✎
14:10
|
(0) запрет запросов в цикле - это религия, не верь в дурное
|
|||
14
vi0
02.03.21
✎
14:24
|
"иногда требуемое условие запроса, позволяющее отказаться от выполнения в цикле, сформулировать бывает затруднительно или очень сложно. В этом случае как минимум нужно вынести создание запроса за пределы цикла, а в цикле изменять только параметры запроса. Это позволит избежать многократной синтаксической проверки текста запроса"
https://its.1c.ru/db/pubqlang/content/150/hdoc |
|||
15
VS-1976
02.03.21
✎
14:59
|
(14) Если данные нужно не сразу, то можно и после открытия формы получить их, к примеру в фоновом задании
|
|||
16
ДедМорроз
02.03.21
✎
15:19
|
Как бы,не стоит бояться запроса в цикле,если он по индексу,так как несколько поисков по этому индексу или все равно будут запросы в цикле или исключение индекса.
|
|||
17
RomaH
naïve
02.03.21
✎
15:32
|
ну как бы есть нормы и правила, -
Не использовать запросы в цикле - из https://its.1c.ru/db/pubqlang/content/150/hdoc по сути, был бы не ленивым - сразу написал бы что-то вроде второго варианта из (0), и даже мысли бы не было переписать на цикл а тут вон как... |
|||
18
H A D G E H O G s
02.03.21
✎
15:40
|
(16) Запрос в цикле и цикл в запросе - это краааайне разные вещи.
|
|||
19
ДедМорроз
02.03.21
✎
15:56
|
(18) в нормальном sql без разницы.
Не забываем,что любой запрос,это цикл движения курсора,а вот где он движется,это уже другой вопрос. Понятно,что сканирование индекса по списку можно делать,предварительно упорядочив список,но не всякий индекс позволяет продолжить сканирование из середины также эффективно,как сначала. |
|||
20
ДедМорроз
02.03.21
✎
15:58
|
Например,как соединить две таблицы
Проще из упорядочить и по ленточке пробежать,а можно в лоб,для каждой строки одной делать поиск по другой. И тут все зависит от объема данных. |
|||
21
H A D G E H O G s
02.03.21
✎
16:26
|
(19) А причем тут SQL, если запрос выплняется из 1С? Вот задержки на отправку запроса и получение ответа - и есть основные затраты на запрос в цикле.
|
|||
22
H A D G E H O G s
02.03.21
✎
16:28
|
"Понятно,что сканирование индекса по списку можно делать,предварительно упорядочив список,но не всякий индекс позволяет продолжить сканирование из середины также эффективно,как сначала."
пшшшш, набор букав. |
|||
23
H A D G E H O G s
02.03.21
✎
16:31
|
(21) ну и подобрать план запроса по статистике, но я думаю, там все быстрее.
|
|||
24
vi0
02.03.21
✎
16:45
|
(21) т.е. работа sql в сумме будет та же, а накладные расходы чисто на 1с?
не замерял, но верится слабо |
|||
25
Said_We
03.03.21
✎
17:14
|
(0) Во втором запросе где параметр "И ЗначенияДляПодстановок.ИмяПоля В (&МассивИмемПолей)" устанавливается не увидел.
ИмяПоля - строка 150, у у вида документа какая разрядность? Эти поля измерения? Индексы есть по этим полям? Зачем такая большая разрядность для текстового поля с именем? |
|||
26
Said_We
03.03.21
✎
17:16
|
Первый запрос выполняешь 25 раз - параметры одни и те же или меняешь перед вызовом запроса? Так на всякий случай спрошу.
|
|||
27
ДедМорроз
03.03.21
✎
22:44
|
Накладные расходы на передачу данных не так существенны,как построение плана запроса.
Для исключения повторного построения плана в sql есть специальная конструкция prepare-execute,да и в 1с,если создать запрос один раз,а потом только менять параметры,то повторной трансляции быть не должно. Конечно,если sql отдельно,то передача запроса по сети и получение ответа тоже занимает время,но его можно учитывать,когда таблицы маленькие и сама выборка по ним занимает время меньшее,чем прочие действия. |
|||
28
Волшебник
03.03.21
✎
23:03
|
У профессионалов запросы в циклах не тормозят!
|
|||
29
assasu
04.03.21
✎
05:31
|
(0) запрос в цикле писать можно. Если количество итераций цикла зависит от программиста, а не от действий пользователя.
|
|||
30
RomaH
naïve
04.03.21
✎
07:04
|
(25) документ - ссылка
разрядность - что бы было .... м.б ИмяТабличногоПоля.ИмяХитровыдуманногоРеквизита в измерениях все три не индексированы - добавление индекса добавляет время выполнения запроса параметр естественно меняю (имя поля) МассивИменПолей - это Массив имен полей - т.е. строк |
|||
31
Said_We
04.03.21
✎
11:46
|
Индекс по строкам 150 - это многовато. Какая максимальная длина которая содержится по факту в регистре в поле "ИмяПоля"?
|
|||
32
Said_We
04.03.21
✎
11:48
|
В каком порядке идут измерения в регистре? Сколько измерений и какие типы с размерностью?
|
|||
33
RomaH
naïve
04.03.21
✎
11:58
|
||||
34
Said_We
04.03.21
✎
12:07
|
Составных типов нет?
|
|||
35
Said_We
04.03.21
✎
12:12
|
Судя по переписке выше есть....
"ТипДокумента - составной - Строка + Справочник.ИдентификаторыОбъектовМД" Строка сколько? |
|||
36
Said_We
04.03.21
✎
12:14
|
"макс длина сейчас 62" - т.е. со 150 смело можно уменьшить до 100.
|
|||
37
Said_We
04.03.21
✎
12:15
|
На сколько целесообразно использовать составной тип в измерении "ТипДокумента"? Строка сейчас используется хоть в одном случае?
|
|||
38
RomaH
naïve
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 не переделаешь
|
|||
41
youalex
04.03.21
✎
13:39
|
(38) в профайлере посмотри какие запросы генерятся.
есть подозрение что условие ЗначенияДляПодстановок.ИмяПоля В (&МассивИмемПолей) порождает неявное создание ВТ по этому массиву. |
|||
42
H A D G E H O G s
04.03.21
✎
14:33
|
Давно бы уже на план запроса посмотрели бы и не гадали.
|
|||
43
toypaul
гуру
04.03.21
✎
15:57
|
Разница в секунду абсолютно ничтожна. Вот когда записей количество отборов сотни тысяч и в итоге В может выполняться пол дня, а 100 тыс раз за пару минут - вот это да.
Это называется криворукие разработчики МС СКЛ. Этой проблеме хренова туча лет, а они все еще не умеют разбивать список ИЛИ на несколько запросов. Ну или я не знаю - написать человеческий оптимизатор. Сколько уже можно обмусоливать эту проблему? |
|||
44
H A D G E H O G s
04.03.21
✎
16:13
|
(43) Это называется некомпетентность. Ваша.
|
|||
45
ViSo76
04.03.21
✎
16:30
|
(33) Имя поля может сделать справочником?
А что за задача такая, что такой регистр пришлось делать? |
|||
46
toypaul
гуру
04.03.21
✎
17:02
|
(44) ты я так понимаю любишь всякими извращениями заниматься, да? вместо того чтобы написать в запрос Поле В (&Список), выполнить сотню таких запросов.
очень же приятно таращить свою компетентность в таких извращениях. нормальный инструмент не должен заставлять разработчика такой фигней страдать. нормальный инструмент сам должен внтури себя разбить это на 100 запросов. если об этом известно уже с десяток лет. ну нет. нам же нужны специалисты по оптимизации, которые будут надувать губы ... у ... да у вас тут несколько ИЛИ и условие по списку. |
|||
47
Вафель
04.03.21
✎
17:29
|
смысл страдать всей этой х..ней, если 2 запрос вообще не решает изначальную задачу?
|
|||
48
H A D G E H O G s
04.03.21
✎
18:44
|
(46) Выдыхайте. Поле В (&Список) нормально отрабатывается SQL-ем
|
|||
49
Исновая
04.03.21
✎
18:52
|
Зачем цикл? Пользуй рекурсию
|
|||
51
ДедМорроз
05.03.21
✎
23:28
|
Запрос с В при большом количестве элементов в может исполняться как соединение,но перед этим список упорядочивается,тогда время выполнения не будет большим.
Если же в лоб,то оптимизатор sql будет выполнять сканирование по индексу с поиском в массиве,а поиск в массиве - это его перебор. |
|||
52
Said_We
09.03.21
✎
10:50
|
(38) По строкам большой длины поиск идет не быстро. Максимально сократи размерность. Например до строка(100) или строка(80)
Вместо "ЗначенияДляПодстановок.ИмяПоля В (&МассивИмемПолей)" Можно попробовать как-то так: ЗначенияДляПодстановок.ИмяПоля В (выбрать т.ИмяПоля из ВТ_МассивИмемПолей как т) ВТ_МассивИмемПолей предварительно создать и проиндексировать по "ИмяПоля". Пробуй. |
|||
53
Said_We
10.03.21
✎
12:30
|
(0) Попробовал?
|
|||
54
Said_We
10.03.21
✎
12:50
|
(38) "Первые 10" всегда быстрее чем полная выборка, в которой много записей. Чем больше записей в полной выборке, тем больше разница во времени. "Первые 1" быстрее чем "Первые 10", но увидеть это иногда можно только в миллисекундах. Почему иногда? Потому что "Первые ХХХ" может относится не к итоговой выборке.
|
|||
55
H A D G E H O G s
10.03.21
✎
12:57
|
(54) Первые 10 останавливают скан, как только нашли Первые 10. Которые могли быть рядом, просто из за пропуска предиката поиска. Ваш КЭП.
|
|||
56
Said_We
10.03.21
✎
15:33
|
(55) Это, наверное, не мне, а ответ (38).
|
|||
57
Said_We
11.03.21
✎
15:13
|
Не интересно уже (0) пробовать что либо. :-)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |