Выгрузка или Выборка из запроса

1. 30.10.17 17:57 Сейчас в теме
Доброго времени суток, уважаемые! Суть в следующем: подскажите, что будет быстрее? запрос.выполнить.выбрать(), или же запрос.выполнить.выгрузить(), и уже после обходим строки таблицы значений? Если можно, то скиньте пруфы. Заранее спасибо!
Ответы
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
2. alex-l19041 8 30.10.17 18:18 Сейчас в теме
если данных не очень много, то разницы нет
3. Boneman 275 30.10.17 18:27 Сейчас в теме
Лишняя операция, никак не может ускорить работу.
Но иногда, удобно запрос выгрузить в ТЗ, и работать с ней, преобразовывая так и этак.
А если просто, обойти результат запроса, то выгрузка в ТЗ не нужна.
4. herfis 404 30.10.17 18:36 Сейчас в теме
А напомните, выборка запроса в память все грузит сразу (как ТЗ) или динамически из временных файликов подкидывает данные в память по мере обхода?
Если второе, то на разных сценариях возможны разные результаты.
5. spacecraft 30.10.17 18:37 Сейчас в теме
(4) если мне память не изменяет, для sql выбирается что-то вроде 1024 записей. И потом при необходимости подгружается. Для файловой сразу в память.
6. herfis 404 30.10.17 18:41 Сейчас в теме
(5) Для сервера приложений, в смысле? Из БД же в любом случае целиком тащится.
7. spacecraft 30.10.17 18:46 Сейчас в теме
(6) для динамических списков это точно так работает. Для просто запроса не помню, используется этот же механизм или нет...
8. herfis 404 30.10.17 18:49 Сейчас в теме
(7) Точно не используется. Динамические списки - отдельная тема. Чтобы возможно было выполнять порционное считывание, запросы динамических списков имеют ограничения.
9. spacecraft 30.10.17 18:49 Сейчас в теме
10. herfis 404 30.10.17 18:51 Сейчас в теме
(9) Это не оно. Динамические выборки - это про Справочники.Номенклатура.Выбрать()
13. spacecraft 30.10.17 19:32 Сейчас в теме
(10) согласен, что это не совсем то. Но сейчас не найду.
Помню точно, что для выборки sql была оптимизация. Она несколько раз менялась. Это внутренний механизм платформы, который не афишируется открыто. Им нельзя управлять.
Но оптимизация была.
Как вариант, если есть желание проверить, можно попробовать сделать запрос на очень большую выборку данных. И добиться, чтоб он падал по памяти (а не кол-ву таблиц) на Выгрузить.
Потом его же на Выбрать. Если не упадет, то данные при Выбрать читаются пакетно.
15. herfis 404 30.10.17 22:47 Сейчас в теме
(13)
Если не упадет, то данные при Выбрать читаются пакетно.

Читаются пакетно ОТКУДА? Из БД? Как вы это себе представляете? Как тяжеленный запрос с кучей промежуточных временных таблиц и подбитием итогов может вычитываться порционно даже в теории?
Я могу допустить, что большая выборка сохраняется на диск и порционно оттуда достается. С этого я и начал разговор в (4).
Причем тоже "помню точно", что где-то я именно про такое и слышал.
16. spacecraft 30.10.17 23:43 Сейчас в теме
(15) мы наверно о разных вещах говорим. Сам запрос выполнится полностью с получением данных.
Весь вопрос в том, результат полностью будет передан или пакетами.
АлександрЯрославичъ; Gang031; +2 Ответить
11. Dream_kz 113 30.10.17 19:24 Сейчас в теме
(4) Помнится мне, что Выборка как раз порционно как-то все достает, а Выгрузка в ТЗ все сразу выгружает в ОЗУ, поэтому рекомендуется использовать Выборку (самой 1С рекомендуется). Пруфов не будет, где-то слышал/читал, найти сейчас сложно будет.

(1) По идее быстрее будет выгрузка в ТЗ, достаем все из БД, и грузим в память, но памяти должно хватать на загрузку всей таблицы, то есть выгрузка не всегда оптимальна. На тех же экзаменах 1С запрещают просто так использовать таблицу значений. Я на своей практике всегда использую выборку, когда не нужна вся таблица целиком (например для специфических отборов из таблицы значений, чтобы не сбрасывать выборку каждый раз).
12. Onwardv 30.10.17 19:30 Сейчас в теме
Через выгрузить() хуже.
Если данных много, то может отвалиться с ошибкой "Не хватает памяти".
А через Выбрать() не отвалиться. Будете ждать окончания выполнения цикла
Пока Выборка.Следующий() до посинения :)
14. Fox-trot 125 30.10.17 20:23 Сейчас в теме
а ежели выгрузить, то еще и данные менять мона
17. Gang031 31.10.17 08:59 Сейчас в теме
Коллега по работе говорит, что в случае, если обходить методом выбрать(), то каждый раз при новой итерации мы обращаемся к серверу, так ли это? ТО биш, если у нас в выборке 1000 записей, то будет 1000 обращений к серверу
18. Dream_kz 113 31.10.17 09:11 Сейчас в теме
19. DenisCh 31.10.17 09:21 Сейчас в теме
(17)Коллега не прав.
Потому что (из справки)
Примечание:

Получение выборок очень большого размера (более 64Mb) требует наличия достаточного количества свободного места на диске, используемом для размещения временных файлов сервера и клиента.
23. herfis 404 31.10.17 11:02 Сейчас в теме
(19) Вооот. Т.е. выборка из результата запроса использует временные файлы. В отличие от ТЗ, которая полностью в памяти.
Меня всегда интересовал вопрос:
Когда, скажем, через ADO делается обход RecordSet - драйвер уже имеет весь RecordSet на клиенте, или СУБД как-то удерживает весь результат запроса у себя и отдает его драйверу порционно по сетке по мере обхода?
20. succub1_5 79 31.10.17 09:21 Сейчас в теме
(17)обработка Запроса всегда на Сервере или нет?
ИМХО Выборка лучше если надо с данными запроса поработать, если просто заполниь ТЗ (или ТЧ документа к примеру) и в запросе выбрали все что надо, то можно сразу Выгрузить (но не более n строк, вроде и в SQL есть ограничения, и в 1С, и в документах).
21. spetzpozh 31.10.17 10:30 Сейчас в теме
Экзамен "1С:Специалист" по платформе "1С:Предприятие 8"
http://static.1c.ru/rus/partners/training/files/ATT83PL.rtf

Список наиболее часто встречающихся ошибок, характерных для любой учетной задачи:
- Выгрузка результата запроса в промежуточную таблицу (например, в таблицу значений) без необходимости (-1 балл)
klaus38; naumenko_alex@mail.ru; АлександрЯрославичъ; Gang031; +4 Ответить
22. Skill 31.10.17 10:34 Сейчас в теме
(0) В обоих случаях вы получаете данные полностью, но при выгрузке вы еще создаете ТЗ, а при большом количестве данных это занимает много времени, но иногда впоследствии работа с ТЗ более удобна. Что использовать ваш выбор, но считается некорректным без особой необходимости выгружать результат в ТЗ.
24. spetzpozh 31.10.17 11:11 Сейчас в теме
https://its.1c.ru/db/v8std/content/-2145782922/hdoc
Система стандартов и методик разработки конфигураций для платформы 1С:Предприятие 8
Оптимизация использования оперативной памяти

2. При потенциально неограниченных выборках данных из ИБ следует получать данные из базы порциями фиксированного размера.
Например, неправильно:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Наименование,
| Номенклатура.ВидНоменклатуры
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";

// Выгрузка всего справочника в таблицу значений
Номенклатура = Запрос.Выполнить().Выгрузить();
Для каждого ПозицияНоменклатуры Из Номенклатура Цикл
// Обработка элемента справочника
// ...
КонецЦикла;

поскольку весь результат запроса сразу помещается в память, в таблицу значений.
Также неправильно:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Наименование,
| Номенклатура.ВидНоменклатуры
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";

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

поскольку и в этом случае при выполнении запроса его результат будет сначала считан в память целиком (*).


* Примечание. Если используется 32-битная версия платформы, и размер результата запроса превосходит размер имеющейся памяти, то данные будут записаны на диск, а затем считаны оттуда в процессе вызовов Выборка.Следующий().
Показать
artir; klaus38; naumenko_alex@mail.ru; АлександрЯрославичъ; molot; Irwin; herfis; Gang031; +8 Ответить
28. artir 22.02.21 13:25 Сейчас в теме
(24) можно пример такого порционного получения данных ?
25. Irwin 362 31.10.17 14:40 Сейчас в теме
Выборка сначала пишется в файл на диск, потом последовательно обходится результат из этого файла. У Бурмистрова в курсе по оптимизации есть видеоурок, где он наглядно показывает как формируется этот файл, в какой момент и пр.
Поэтому без необходимости лучше не пользоваться Выгрузить().
АлександрЯрославичъ; Zemko; spetzpozh; +3 Ответить
26. АлександрЯрославичъ 26.03.19 18:27 Сейчас в теме
Поделюсь.
Есть список на форме. Запрос выгружался в ТЗ и через метод списка "Загрузить()", добавлялись данные. При 30000 записях база намертво висла. При 15-20 тысячах кое-как проглатывала и все же отрабатывала.
Переделал под обход выборки - большие объемы стали загружаться.
27. Chai Nic 147 13.06.19 16:50 Сейчас в теме
Выборка МОЖЕТ использовать диск, но практически всегда использует память. Насколько я знаю (проверял тестовым примером на каком-то релизе из ветки 8.3), по расходу памяти практически одинаковы и выгрузка и выборка. По крайней мере, пока не упираешься в нехватку памяти. А если результат запроса настолько велик, что не помещается в память - значит, что-то не так с запросом или с постановкой задачи...
Drivingblind; +1 1 Ответить
Оставьте свое сообщение
Вопросы с вознаграждением