|
Быстрая загрузка данных из базы SQL | ☑ | ||
---|---|---|---|---|
0
Lepochkin
29.09.14
✎
11:41
|
Добрый день, всем. Есть такая задачка. Имеется база SQL. К ней я делаю запрос и получаю данные. Далее эти данные помещаю с таблица значений, таблицу значений передаю как параметр в запрос 1совский и дальше с ней работаю. Дак вот табличка с данными стала ну уж очень большой, и уходит порядка получаса для того, что бы прямым перебором ее запихать в таблицу значений. Есть ли как-нибудь другой способ? Внешний источник данных пробовал. Ничего хорошего.
|
|||
1
КонецЦикла
29.09.14
✎
11:43
|
Временные таблицы? Не, не слышол
|
|||
2
Ерепень
29.09.14
✎
11:43
|
а напрямую запросить? подозреваю, будет то же, что и с внешним источником
|
|||
3
Жан Пердежон
29.09.14
✎
11:45
|
(0) большая это сколько?
|
|||
4
shuhard
29.09.14
✎
11:50
|
(0)[Есть ли как-нибудь другой способ]
засунуть напрямки в табличку 1С на сиквеле |
|||
5
ice777
29.09.14
✎
11:53
|
примерно так:
Вставка = "бла-бла первый запрос" Второй запрос = "......"+ Вставка + "....." |
|||
6
ice777
29.09.14
✎
11:54
|
* "вставку" вставь там, куда ТЗ свою сувал.
это по-простому |
|||
7
ДенисЧ
29.09.14
✎
11:57
|
хм....
А дайте код создание временной таблицы в скуле, чтобы к ней потом запросом 1с можно было обратиться.... (0) И да, код вытяжки покажи.... |
|||
8
Lepochkin
29.09.14
✎
12:03
|
(1) Вот как бы из скуля по временную таблицу 1ски сделать. хочу знать
(3) 4 миллиона записей сейчас и прогнозируется рост (5) Не понял (7) Тут все наверное стандартно Если НЕ RecordSet.EOF() Тогда RecordSet.MoveFirst(); Пока RecordSet.EOF() = 0 Цикл //Состояние("Загрузка данных: "+строка(ИД)); СтрокаТаблицыЗначений = тз.Добавить(); Для НомерКолонки = 0 По RecordSet.Fields.Count-1 Цикл СтрокаТаблицыЗначений[НомерКолонки] = RecordSet.Fields(RecordSet.Fields.Item(НомерКолонки).Name).Value; КонецЦикла; RecordSet.MoveNext(); ИД = ИД + 1; КонецЦикла; КонецЕсли; |
|||
9
ДенисЧ
29.09.14
✎
12:04
|
(8) измени вот эту строку
RecordSet.Fields(RecordSet.Fields.Item(НомерКолонки).Name).Value; перед циклом получай все элементы Fields в переменные. Намного быстрее будет. |
|||
10
Lepochkin
29.09.14
✎
12:15
|
(9) Не понял как этот должно выглядеть
|
|||
11
ДенисЧ
29.09.14
✎
12:16
|
имяПеременной0 = RS.Fields(0);
.... ИмяПеременнойN = RS.Fields(0); пока не RS.EOF Цикл Значение0 = имяПеременной0.Value; .... rs.MoveNext(); КонецЦикла |
|||
12
Lepochkin
29.09.14
✎
12:24
|
Как-то так получилось. Вроде работает
Для НомерКолонки = 0 По RecordSet.Fields.Count-1 Цикл МассивПеременных.Добавить(RecordSet.Fields(НомерКолонки)); КонецЦикла; Если НЕ RecordSet.EOF() Тогда RecordSet.MoveFirst(); Пока RecordSet.EOF() = 0 Цикл //Состояние("Загрузка данных: "+строка(ИД)); СтрокаТаблицыЗначений = тз.Добавить(); Fields = RecordSet.Fields; Для НомерКолонки = 0 По RecordSet.Fields.Count-1 Цикл СтрокаТаблицыЗначений[НомерКолонки] = МассивПеременных[НомерКолонки].Value; КонецЦикла; RecordSet.MoveNext(); ИД = ИД + 1; КонецЦикла; КонецЕсли; Вечером посмотрим прирост в скорости. Есть еще какие-нибудь варианты ускорения? |
|||
13
ДенисЧ
29.09.14
✎
12:27
|
(12) Посмотри на GameWithFire.
Дальше некуда. |
|||
14
Зеленый пень
29.09.14
✎
12:29
|
Эти 4 млн. строк в SQL часто обновляются?
Если нет, то я бы тащил только новые и добавлял их в рег.сведений в базе 1С. Можно делать такое обновление РС в фоновом режиме. А запрос по РС строить. |
|||
15
КонецЦикла
29.09.14
✎
12:30
|
(8) В таблицу SQL с нужным индексом... или в какой-то служебный регистр сведений
|
|||
16
МихаилМ
29.09.14
✎
13:05
|
читайте про метод ado getrows http://msdn.microsoft.com/en-us/library/windows/desktop/ms675120(v=vs.85).aspx
если 1с - клиент- серверная , то можно в таблицы бд 1с (РС)записать обработать, затем очистить можно ускорить чтение данных из скл если написать clr-метод который превратит выборку в тз спрятанную в хранилище Значений |
|||
17
Drac0
29.09.14
✎
13:10
|
(0) Что ты потом с этими данными делаешь в 1С-ом запросе?
|
|||
18
Широкий
29.09.14
✎
13:30
|
BULK INSERT?
|
|||
19
Lepochkin
29.09.14
✎
13:32
|
(14) Собственно так и делаю. Получаю данные раз в день, пишу только изменения в регистр, а пользователи уже с регистром работают. Задание стало работать 40 минут. Из них 30 получение данных. Пока еще все терпимо, доводить нетерпимо не хочется.
|
|||
20
Зеленый пень
29.09.14
✎
13:37
|
(19) Не совсем понятно. Если получение данных сделать заранее - то останется только отчет построить, т.е. 10 сек.
|
|||
21
Cyberhawk
29.09.14
✎
13:40
|
(19) Храни в приемнике дату актуальности таблицы, а из источника получай только записи, которые актуальнее даты актуальности приемника. Ну, это прокатит, если во внешнем источнике есть timastamp
|
|||
22
Cyberhawk
29.09.14
✎
13:41
|
(21) * timestamp
|
|||
23
Lepochkin
29.09.14
✎
13:47
|
с getrows вот такой косяк.
Ошибка при вызове метода контекста (GetRows) COMSafeArray = RecordSet.GetRows(); по причине: Произошла исключительная ситуация (Provider): Недостаточно памяти для завершения операции на TOP 1000 очень шустро отработала, а вот на полной таблице не взлетело |
|||
24
Lepochkin
29.09.14
✎
13:48
|
(20)Отчеты все летают. Данные просто нужны к концу рабочего дня и становится критичное время их закачки в 1ску.
|
|||
25
YFedor
29.09.14
✎
13:50
|
Не понял зачем здесь вообще ТЗ и запрос в 1С
|
|||
26
Lepochkin
29.09.14
✎
13:52
|
Хотя бы для того что бы в регистр сведений записать ссылку на номенклатуру, а не ее код, который мне отдает сторонняя база SQL. Плюс дублирующие записи отсечь.
|
|||
27
Зеленый пень
29.09.14
✎
13:53
|
Можно в SQL повесить триггеры, которые в отдельную таблицу будут добавлять измененные строки, и там всё что угодно можно замутить.
|
|||
28
rsv
29.09.14
✎
14:01
|
(0) Так что с внешним источником ? Получив оный джойните с чем хотите и не надо никуда перезаливать. Джойнить получится токма в СКД.
|
|||
29
rsv
29.09.14
✎
14:02
|
4 000 000 это не объем.
|
|||
30
rsv
29.09.14
✎
14:05
|
в принципе они и были придуманы (источники) для этих целей - для соединения (объеденения ) в единой среде выполнения
|
|||
31
Lepochkin
29.09.14
✎
14:06
|
При тесте внешнего источника памяти сожрал процесс 2 гига и помер.
|
|||
32
rsv
29.09.14
✎
14:06
|
Поля поиндексируйте в таблице внешней . может и взлетит.
|
|||
33
rsv
29.09.14
✎
14:07
|
(31) Ставьте топ 100 при тестах.
|
|||
34
Lepochkin
29.09.14
✎
14:07
|
Пробовал. Та же история
|
|||
35
Lepochkin
29.09.14
✎
14:08
|
(33) Первый запуск на TOP 1000 делаю. Если все взлетает, то беру целиком.
|
|||
36
neckto
29.09.14
✎
14:20
|
(19) На этапе получения данных отсекай уже обработанные, будешь вытаскивать небольшой объем изменений.
|
|||
37
Lepochkin
29.09.14
✎
14:26
|
(36) Сравнения в цикле делаются медленные чем в запросе. А скулявая база не держит срез последний 1совский.
|
|||
38
neckto
29.09.14
✎
14:31
|
(37) есть у тебя таблица №1: <ID> <Данные>
Создай в SQL-ной базе таблицу №2: <ID>. Когда получаешь данные, получай из таблицы №1, за исключением данных в таблице №2. Когда в 1С обработаешь записи, пиши в таблицу №2 <ID>. <ID> - одно или комбинация полей. |
|||
39
Lepochkin
29.09.14
✎
14:49
|
Со структурой в скульной базе можно конечно попробовать оптимизец навести. Но данных все равно много будет. Так что начальная задачка остается.
|
|||
40
neckto
29.09.14
✎
14:53
|
(39) Делай обмен чаще.
|
|||
41
Lepochkin
29.09.14
✎
14:57
|
Чаще плохо. Посчитать не по конечным данным юзеры могут.
|
|||
42
КонецЦикла
29.09.14
✎
15:00
|
(37) Соединение в запросе, а не сравнение в цикле
Все там моментально будет если применить моск |
|||
43
Жан Пердежон
29.09.14
✎
15:00
|
может есть возможность сразу готовые данные получать из SQL?
либо часть данных из 1С помещать в ВТ SQL, а потом уже тянуть запросом результат? |
|||
44
neckto
29.09.14
✎
15:00
|
(41) Можно поиграться признаком Активность записи РС.
|
|||
45
Надо работать
29.09.14
✎
15:01
|
(23) А частями грузить, по миллиону записей допустим?
|
|||
46
Drac0
29.09.14
✎
15:03
|
(0) Из 4 млн. считаных записей, сколько пишутся в регистр?
|
|||
47
Йохохо
29.09.14
✎
15:15
|
(46) вангую "500 штук" и проблема добавить в запрос вхере Выражение
|
|||
48
Lepochkin
29.09.14
✎
15:19
|
(46) 70% примерно. Частями получать тоже можно. Даже реализовано.
|
|||
49
Drac0
29.09.14
✎
15:21
|
(48) Да ,тогда особо не выиграешь. Тогда, ИМХО, делать запись в технический регистр прямым запросом ,а потом уже с ним работать через 1С.
|
|||
50
Lepochkin
29.09.14
✎
15:24
|
(49) Вот наверное по такому пути я и пойду.
|
|||
51
Serginio1
29.09.14
✎
15:41
|
Если табличка регистр сведений, то проще использовать Merge и напрямую писать в регистр сведений
v8: _SimpleKey и его установка |
|||
52
Kamas
29.09.14
✎
15:44
|
(51) так что там с клавиатурой то решилось??
|
|||
53
Serginio1
29.09.14
✎
16:13
|
(52) Без понятия
|
|||
54
Lepochkin
29.09.14
✎
17:23
|
Переделка из (12) ускорила примерно в 2 раз.
|
|||
55
МихаилМ
29.09.14
✎
18:03
|
(54)
избавьтесь от RecordSet.Fields.Count-1 и будет еще быстрей если будете в getrows() получать не все данные а порциями (например по 50000 записей ) будет еще быстрей. |
|||
56
Serginio1
29.09.14
✎
18:22
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |