|
Скорость экспорта в FireBird | ☑ | ||
---|---|---|---|---|
0
kanalex
01.09.12
✎
23:44
|
Господа, посоветуйте, что делать у кого был такой опыт.
Есть задача экспортировать всю информацию из 1С в FireBird один раз и потом написать в 1С подписки на события, по которым будут выгружаться измененные или добавленные данные. Вообщем задача решена, но не радует скорость:( Не очень большая база (2.5Г) локально в файловом режиме... Сейчас запущен экспорт всего подряд, что должно экспортироваться. Всего порядка 65 объектов... справочники, документы и их табличные части, регистры сведений, перечисления... Компьютер здесь конечно не самый шустрый, но все таки... Выгрузка длится уже 16 часов.... Боюсь, что завершится она не раньше 20-24-х часов. Файл FireBird сейчас уже 550М. Можно что-нибудь сделать для ускорения процесса? |
|||
8
ПесняПроЗайцев
05.09.12
✎
22:15
|
(5) в свое время я работал с fb, но он многое не умеет, просто бесплатный проект. Сталкивался с тем, что синтаксис tsql немного иной. Что-то изменилось?
|
|||
9
Адимр
06.09.12
✎
00:53
|
Не знаю как в firebird но в sqlite INSERT INTO FOO SELECT * FROM FOO из 21 итерации (2 млн записей) за 15 секунд на обычной офисной машинке.
|
|||
10
Чарльз Треч
06.09.12
✎
01:09
|
(0) Это http://www.ibprovider.com/rus/index.html использовать не пробовал?
|
|||
11
Torquader
06.09.12
✎
02:09
|
(8) Он не то, что не умеет, у него архитектура немного другая.
Если читать документацию про FireBird, то там много всего описано про одновременное исполнение транзакций, уровни блокировок и т.п., половина из которого просто в других серверах не встречается, так как не обеспечивает правильного выполнения транзакций. Но, в FireBird можно писать SELECT процедуры и выдавать в виде табличного результата произвольный набор данных, что в других SQL просто нет - как объектно-ориентированная игрушка он вполне годится. Также очень интересный способ использования чисел со смещённой точкой, но вся эта фича поддерживается только при работе в Си через библиотеки. Ну и массивы - тоже интересная вещь. |
|||
12
kanalex
06.09.12
✎
10:17
|
(10) пока не пробовал.
|
|||
13
kanalex
06.09.12
✎
10:18
|
(4) пока на время отладки база файловая.
Потом будет на скуле, думаю |
|||
14
kanalex
06.09.12
✎
10:19
|
(8) в моей задаче ничего хитрого в запросах не приходится делать.
Пока во всяком случае. |
|||
15
rs_trade
06.09.12
✎
11:27
|
(13) для скулевой базы я бы экспорт настроил через интегрейшн сервисы.
|
|||
16
MMF
06.09.12
✎
12:55
|
(0) не надо "Надо собрать каждый запрос и т.д...". Выполняй параметризированные запросы, перед циклом выгрузки сделай их prepared - скорость вырастит в разы.
|
|||
17
kanalex
16.09.12
✎
23:10
|
Что-то странный результат получился по тестам с IBProvider:(
Или я не так с ним обращаюсь? Функция СоединитьсяСБазойIBProvider() //Установим соединение с БД Путь = Константы.тт_СтрокаКоннектаКFireBird.Получить(); Логин = Константы.тт_ЛогинFireBird.Получить(); Пароль = Константы.тт_ПарольFireBird.Получить(); стрПодключения = "data source="+ Путь + ";user ID= " + Логин + ";password=" + Пароль + "masterkey;auto_commit=true;ctype=win1251"; Connection = Новый COMОбъект("ADODB.Connection"); Connection.Provider = "LCPI.IBProvider"; Connection.ConnectionString = стрПодключения; Попытка Connection.Open(); Исключение Сообщить ("Проблемы с подключением к InterBase - " + ОписаниеОшибки()); Возврат ""; КонецПопытки; Возврат Connection; КонецФункции Функция СоединитьсяСБазой() //Установим соединение с БД COMСоединение = Новый COMОбъект("ADODB.Connection"); Путь = Константы.тт_СтрокаКоннектаКFireBird.Получить(); Логин = Константы.тт_ЛогинFireBird.Получить(); Пароль = Константы.тт_ПарольFireBird.Получить(); COMСоединение.ConnectionString = "driver={Firebird/InterBase(r) driver};server=" + Путь + ";uid=" + Логин + ";pwd=" + Пароль + ";database=" + Путь + ";"; COMСоединение.ConnectionTimeOut = 1200; COMСоединение.CursorLocation = 3; Попытка COMСоединение.Open(COMСоединение.ConnectionString); Исключение Отказ = Истина; COMСоединение = Неопределено; Предупреждение("Невозможно установить соединение - " + ОписаниеОшибки()); КонецПопытки; Возврат COMСоединение; КонецФункции Процедура СохранитьРеквизитВТаблицуHEAD(ОбъектADO_proc, TableNameString_proc, TABL_HEAD_ACTV_proc, HeadIDString, TABL_HEAD_TYPE, TABL_HEAD_STAT, TABL_HEAD_1CCO) //Запись в таблицу HEAD ТекстЗапроса = "INSERT INTO TAB_TABL_HEAD(TABL_HEAD_CODE, TABL_HEAD_NAME, TABL_HEAD_STAT, TABL_HEAD_TYPE, TABL_HEAD_ACTV, TABL_HEAD_SYST, TABL_HEAD_1CCO) VALUES(" + HeadIDString + " , '" + TableNameString_proc + "', " + TABL_HEAD_STAT + ", " + TABL_HEAD_TYPE + ", " + TABL_HEAD_ACTV_proc + ", '" + TABL_HEAD_SYST + "', '" + TABL_HEAD_1CCO + "');"; ОбъектADO_proc.CommandText = ТекстЗапроса; Попытка Рекордсет = ОбъектADO_proc.Execute(); Исключение Сообщить(ТекстЗапроса); Предупреждение("Не получилось выполнить запрос в таблицу HEAD!" + " - " + ОписаниеОшибки()); Отказ = Истина; Возврат; КонецПопытки; КонецПроцедуры Процедура Основная() Если IBProvider Тогда COMСоединение = СоединитьсяСБазойIBProvider(); Иначе COMСоединение = СоединитьсяСБазой(); КонецЕсли; КомандаАДО = КомандаАДО(COMСоединение); //Тут для примера.... Там много чего выгружается. Запросы все однотипные в две таблицы поочередно //Сначала в HEAD потом в BODY Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ " + ИмяПеречисления + ".Ссылка, " + ИмяПеречисления + ".Порядок |ИЗ | Перечисление." + ИмяПеречисления + " КАК " + ИмяПеречисления; Состояние("Выполняем выгрузку констант..." + ИмяПеречисления); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); Пока Выборка.Следующий() цикл TableNameString = ИмяТаблицы; HeadIDString = СгенерироватьID(КомандаАДО, "TABL_HEAD_CODE"); СохранитьРеквизитВТаблицуHEAD(КомандаАДО, TableNameString, TABL_HEAD_ACTV, HeadIDString, TABL_HEAD_TYPE, TABL_HEAD_STAT, ПолучитьИмяЗначенияПеречисления(Выборка.Ссылка)); //Запись реквизитов в таблицу BODY СохранитьРеквизитВТаблицуBODY(КомандаАДО, HeadIDString, ИмяРеквизита, Выборка.Ссылка); //Наименование КонецЦикла; КонецПроцедуры Результат теста: Ограничил по 100 записей в запросах 1С: IBProvider: Начали: 16.09.2012 22:34:37 Закончили: 16.09.2012 22:37:12 2 мин 35 сек Начали: 16.09.2012 22:51:24 Закончили: 16.09.2012 22:53:55 2 мин 31 сек ODBC: Начали: 16.09.2012 22:39:05 Закончили: 16.09.2012 22:41:31 2 мин 26 сек Начали: 16.09.2012 22:47:09 Закончили: 16.09.2012 22:49:33 2 мин 24 сек Выгружено по 20612 записей в каждом тесте Что не так??? |
|||
18
Стальная Крыса
17.09.12
✎
06:11
|
(17) ну в (16) уже было сказано про "prepared"
|
|||
19
kanalex
17.09.12
✎
08:02
|
(18) к сожалению, не катит prepared:(
Запросы выполняются в цикле в две таблицы поочереди. Как тут сделать prepared? |
|||
20
kanalex
17.09.12
✎
12:02
|
INSERT INTO Students (FirstName,LastName) VALUES ('Иванов','Иван'), ('Петров', 'Петр'), ('Сергеев', 'Сергей')
FB такую конструкцию не понимает (проверил и получил сообщение об ошибке). |
|||
21
MMF
17.09.12
✎
12:47
|
(20) Исходя из предположения, что ты единственный пользователь базы на вставку можно получить первое значение генератора для таблицы TAB_TABL_HEAD и вставлять записи без СгенерироватьID, а тупо HeadIDString = HeadIDString + 1;
Не очень понятно, у тебя 1-й записи таблицы HEAD соответствует 1-а запись таблицы Body? странная идея. Лично я бы сделал примитивную ВК для этого дела и не мучался с IBProvider |
|||
22
kanalex
17.09.12
✎
12:52
|
(21) на этапе массового экспорта я единственный..., но потом все это будет привязано к событиям и экспортироваться уже на живой многопользовательской базе. Там я вполне могу оказаться не единственным.
|
|||
23
kanalex
17.09.12
✎
12:54
|
(21) я привел самый примитивный пример.
Конечно в реальности 1-й записи в Head может соответствовать тысячи записей в Body |
|||
24
MMF
17.09.12
✎
13:03
|
(22) ну все равно можно сократить один запрос, используя insert returning, для первичного ключа таблицы-мастера (только сделать поле Pk автоинкрементным)
|
|||
25
kanalex
17.09.12
✎
15:11
|
Процедура Тест()
COMСоединение = СоединитьсяСБазой(); КомандаАДО = КомандаАДО(COMСоединение); ТекстЗапроса = "EXECUTE BLOCK AS |BEGIN |INSERT INTO TAB_TABL_HEAD(TABL_HEAD_CODE, TABL_HEAD_NAME, TABL_HEAD_STAT, TABL_HEAD_TYPE, TABL_HEAD_ACTV, TABL_HEAD_SYST, TABL_HEAD_1CCO) VALUES(14 , 'TAB_BOTP_LIST', 1, 1, 0, 'asdsdee553533-ree43', 'rfs-sdff-4563-gfre-9343'); |INSERT INTO TAB_TABL_HEAD(TABL_HEAD_CODE, TABL_HEAD_NAME, TABL_HEAD_STAT, TABL_HEAD_TYPE, TABL_HEAD_ACTV, TABL_HEAD_SYST, TABL_HEAD_1CCO) VALUES(15 , 'TAB_BOTP_LIST', 1, 1, 0, 'asdsdee553533-ree43', 'rfs-sdff-4563-gfre-9343'); |INSERT INTO TAB_TABL_HEAD(TABL_HEAD_CODE, TABL_HEAD_NAME, TABL_HEAD_STAT, TABL_HEAD_TYPE, TABL_HEAD_ACTV, TABL_HEAD_SYST, TABL_HEAD_1CCO) VALUES(16 , 'TAB_BOTP_LIST', 1, 1, 0, 'asdsdee553533-ree43', 'rfs-sdff-4563-gfre-9343'); |END"; КомандаАДО.CommandText = ТекстЗапроса; Попытка Рекордсет = КомандаАДО.Execute(); Исключение Сообщить(ТекстЗапроса); Предупреждение("Не получилось выполнить запрос в таблицу HEAD!" + " - " + ОписаниеОшибки()); Отказ = Истина; Возврат; КонецПопытки; КонецПроцедуры Вот такой тест отработал.... Попробуем собирать Блоками. Потестируем... |
|||
26
MMF
17.09.12
✎
16:04
|
(25) на длину текста блока есть ограничение. Имхо в 64 кб
|
|||
27
kanalex
17.09.12
✎
17:30
|
(26)
:( Мда... Короткие блоки исполняются. |
|||
28
MMF
17.09.12
✎
17:36
|
(27) ВК спасет отца русской демократии, там и prepared и все что хочешь можно сделать.
Ну а если жестко забиться использованием 1С, то еще попробуй посмотреть настройки базы и сервера: DefaultDbCachePages, ForcedWrites и все остальное прочее. |
|||
29
kanalex
21.09.12
✎
09:08
|
(27) выявилось еще более жесткое ограничение:(
Во всяком случае из 1С через ODBC можно выполнить блок с не более чем 255 строк... тест не показал прироста вообще:( Для теста взята выгрузка 999 элементов справочника Банки Без блоков: Начали: 21.09.2012 8:58:15 Закончили: 21.09.2012 8:59:03 С Блоками: Начали: 21.09.2012 9:00:24 Закончили: 21.09.2012 9:01:13 |
|||
30
kanalex
25.09.12
✎
12:42
|
(27) Да, скорость сильно растет.
Но, если что случается с каналом..., то базу не восстановить. Протестировано: из 10 разрывов связи 9 баз умерло навсегда. |
|||
31
kanalex
25.09.12
✎
12:44
|
Еще вопрос возник...
Как лучше экспортировать ХринилищеЗначения? Надо выгрузить в FB картинки, которые хранятся в базе 1С. Можно это сделать минуя сохранение в файл? Через запрос.??? |
|||
32
kanalex
25.09.12
✎
15:13
|
пока результат таков:
Если СокрЛП(а) = "Хранилище значения" Тогда Если ТипЗнч(Объект.Хранилище.Получить()) = Тип("ДвоичныеДанные") Тогда Возврат Строка(Объект.Хранилище.Получить()); ИначеЕсли Объект.Хранилище.Получить() = Неопределено Тогда Возврат "NULL"; Иначе ДвоичныеДанные = Объект.Хранилище.Получить().ПолучитьДвоичныеДанные(); Возврат Строка(ДвоичныеДанные); КонецЕсли; КонецЕсли; Соотв, в запрос попадают двоичные данные обрезанный до 32К:( |
|||
33
Jofa
25.09.12
✎
15:16
|
Напиши строку подключения
|
|||
34
kanalex
25.09.12
✎
15:17
|
Функция СоединитьсяСБазой()
//Установим соединение с БД COMСоединение = Новый COMОбъект("ADODB.Connection"); Путь = Константы.тт_СтрокаКоннектаКFireBird.Получить(); Логин = Константы.тт_ЛогинFireBird.Получить(); Пароль = Константы.тт_ПарольFireBird.Получить(); COMСоединение.ConnectionString = "driver={Firebird/InterBase(r) driver};server=" + Путь + ";uid=" + Логин + ";pwd=" + Пароль + ";database=" + Путь + ";"; COMСоединение.ConnectionTimeOut = 1200; COMСоединение.CursorLocation = 3; Попытка COMСоединение.Open(COMСоединение.ConnectionString); Исключение Отказ = Истина; COMСоединение = Неопределено; Предупреждение("Невозможно установить соединение - " + ОписаниеОшибки()); КонецПопытки; Возврат COMСоединение; КонецФункции |
|||
35
MMF
25.09.12
✎
15:17
|
(30) "не верю". И что говорит на такую базу IBFirstAidDiagnostic или хотя бы gfix?
|
|||
36
Jofa
25.09.12
✎
15:20
|
База Локальной сети лежит?
|
|||
37
Jofa
25.09.12
✎
15:23
|
АЛЛО
|
|||
38
kanalex
25.09.12
✎
15:23
|
в данном случае при экспорте база лежит на той же машине.
|
|||
39
Jofa
25.09.12
✎
15:25
|
Добавь в конец вот эту строчку : + ";CHARSET=UTF8"
|
|||
40
Jofa
25.09.12
✎
15:25
|
Плюсик тоже добавь
|
|||
41
Jofa
25.09.12
✎
15:27
|
Ну что там у нас получилось?
|
|||
42
Jofa
25.09.12
✎
15:29
|
Строка подключения должна выглядеть вот так :
COMСоединение.ConnectionString = "driver={Firebird/InterBase(r) driver};server=" + Путь + ";uid=" + Логин + ";pwd=" + Пароль + ";database=" + Путь + ";"+ ";CHARSET=UTF8"; |
|||
43
MMF
25.09.12
✎
15:29
|
(32) три раза (в неблагоприятном случае) выполнять Объект.Хранилище.Получить() - мудрое решение
|
|||
44
Jofa
25.09.12
✎
15:30
|
(42) Поторопился вот так :
COMСоединение.ConnectionString = "driver={Firebird/InterBase(r) driver};server=" + Путь + ";uid=" + Логин + ";pwd=" + Пароль + ";database=" + Путь + ";CHARSET=UTF8"; |
|||
45
Jofa
25.09.12
✎
15:31
|
Ну что там?
|
|||
46
MMF
25.09.12
✎
15:32
|
(44) никакой разницы от твоего чарсета в скорости не будет
|
|||
47
Jofa
25.09.12
✎
15:32
|
Если не Секрет что там у вас такого сурового храниться в Птичке?
|
|||
48
kanalex
25.09.12
✎
15:32
|
у нас база в 1251 кодировке лежит
|
|||
49
Jofa
25.09.12
✎
15:33
|
(46)Ещё как будет . .Ждёмс отчёт
|
|||
50
Jofa
25.09.12
✎
15:33
|
Укажи 1251
|
|||
51
Jofa
25.09.12
✎
15:35
|
Ну что там??
|
|||
52
kanalex
25.09.12
✎
15:36
|
ждемс...
|
|||
53
Jofa
25.09.12
✎
15:37
|
Надеюсь ты кусочек данных выгружаешь не все?
|
|||
54
kanalex
25.09.12
✎
15:38
|
естессно:)
все выгружается уже третьи сутки:( |
|||
55
Jofa
25.09.12
✎
15:38
|
Если не Секрет что там у вас такого сурового храниться в Птичке ?
|
|||
56
kanalex
25.09.12
✎
15:39
|
в птичке будет храниться консолидированная база по сети...
1С с этим не справляется. 70 представительств по всей стране. базы 1С объемом до 300Гб:( |
|||
57
Jofa
25.09.12
✎
15:40
|
Почему Птичка в Птичке а не СКУЛь?
|
|||
58
Jofa
25.09.12
✎
15:40
|
Почему в Птичке а не СКУЛь?
|
|||
59
kanalex
25.09.12
✎
15:41
|
это не ко мне вопрос.
|
|||
60
Jofa
25.09.12
✎
15:41
|
(56)Круто
|
|||
61
kanalex
25.09.12
✎
15:43
|
(44)
по 100 записей на запрос: Начали: 25.09.2012 15:36:09 Закончили: 25.09.2012 15:40:20 |
|||
62
MMF
25.09.12
✎
15:47
|
(61) выложи скрипт метаданных базы
|
|||
63
kanalex
25.09.12
✎
15:48
|
(62) FB?
|
|||
64
kanalex
25.09.12
✎
15:49
|
(44) 5481 + 41996 записей выгрузилось в FB
|
|||
65
MMF
25.09.12
✎
15:51
|
(63) да
(64) и что, ускорил тебе что-нить чарсет? |
|||
66
kanalex
25.09.12
✎
15:52
|
(65) не ускорил
|
|||
67
MMF
25.09.12
✎
15:53
|
(66) ну дык, ясен перец.
|
|||
68
kanalex
25.09.12
✎
15:56
|
/******************************************************************************/
/*** Generated by IBExpert 2008.02.18 25.09.2012 15:56:09 ***/ /******************************************************************************/ SET SQL DIALECT 3; SET NAMES WIN1251; CREATE DATABASE 'D:\WORK\MM_2012\FbDb\BBB.FDB' USER 'SYSDBA' PASSWORD 'masterkey' PAGE_SIZE 16384 DEFAULT CHARACTER SET WIN1251; /******************************************************************************/ /*** Domains ***/ /******************************************************************************/ CREATE DOMAIN DOM_CHAR AS CHAR(1); CREATE DOMAIN DOM_CODE AS INTEGER; CREATE DOMAIN DOM_FLOAT AS FLOAT; CREATE DOMAIN DOM_INT AS INTEGER; CREATE DOMAIN DOM_ST100 AS VARCHAR(100); CREATE DOMAIN DOM_ST13 AS CHAR(13); CREATE DOMAIN DOM_ST14 AS CHAR(14); CREATE DOMAIN DOM_ST36 AS CHAR(36); CREATE DOMAIN DOM_TEXT AS BLOB SUB_TYPE 1 SEGMENT SIZE 80; CREATE DOMAIN DOM_TIMESTAMP AS TIMESTAMP; /******************************************************************************/ /*** Generators ***/ /******************************************************************************/ CREATE GENERATOR GEN_TABL_BODY_CODE; SET GENERATOR GEN_TABL_BODY_CODE TO 290946; CREATE GENERATOR GEN_TABL_HEAD_CODE; SET GENERATOR GEN_TABL_HEAD_CODE TO 37959; SET TERM ^ ; /******************************************************************************/ /*** Stored Procedures ***/ /******************************************************************************/ CREATE PROCEDURE TAB_TABL_BODY_DEL ( TABL_BODY_CODE INTEGER) AS BEGIN EXIT; END^ CREATE PROCEDURE TAB_TABL_BODY_IU ( TABL_BODY_CODE INTEGER, TABL_HEAD_CODE INTEGER, TABL_BODY_NAME CHAR(14), TABL_BODY_VALT BLOB SUB_TYPE 1 SEGMENT SIZE 80, TABL_BODY_VALF FLOAT, TABL_BODY_VALI INTEGER, TABL_BODY_VALS VARCHAR(100), TABL_BODY_TYPE CHAR(1)) AS BEGIN EXIT; END^ CREATE PROCEDURE TAB_TABL_HEAD_DEL ( TABL_HEAD_CODE INTEGER) AS BEGIN EXIT; END^ CREATE PROCEDURE TAB_TABL_HEAD_IU ( TABL_HEAD_CODE INTEGER, TABL_HEAD_NAME CHAR(13), TABL_HEAD_CTST TIMESTAMP, TABL_HEAD_STAT INTEGER, TABL_HEAD_TYPE INTEGER, TABL_HEAD_ACTV INTEGER, TABL_HEAD_SYST CHAR(36), TABL_HEAD_1CCO CHAR(36)) AS BEGIN EXIT; END^ SET TERM ; ^ /******************************************************************************/ /*** Tables ***/ /******************************************************************************/ CREATE TABLE TAB_TABL_BODY ( TABL_BODY_CODE DOM_CODE NOT NULL, TABL_HEAD_CODE DOM_CODE, TABL_BODY_NAME DOM_ST14, TABL_BODY_VALT DOM_TEXT, TABL_BODY_VALF DOM_FLOAT, TABL_BODY_VALI DOM_INT, TABL_BODY_VALS DOM_ST100, TABL_BODY_TYPE DOM_CHAR, TABL_BODY_VALD DOM_TIMESTAMP ); CREATE TABLE TAB_TABL_HEAD ( TABL_HEAD_CODE DOM_CODE NOT NULL, TABL_HEAD_NAME DOM_ST13, TABL_HEAD_CTST DOM_TIMESTAMP DEFAULT current_timestamp, TABL_HEAD_STAT DOM_INT DEFAULT 0, TABL_HEAD_TYPE DOM_INT DEFAULT 0, TABL_HEAD_ACTV DOM_INT DEFAULT 0, TABL_HEAD_SYST DOM_ST36, TABL_HEAD_1CCO DOM_ST36 ); /******************************************************************************/ /*** Primary Keys ***/ /******************************************************************************/ ALTER TABLE TAB_TABL_BODY ADD CONSTRAINT PK_TAB_TABL_BODY PRIMARY KEY (TABL_BODY_CODE); ALTER TABLE TAB_TABL_HEAD ADD CONSTRAINT PK_TAB_TABL_HEAD PRIMARY KEY (TABL_HEAD_CODE); /******************************************************************************/ /*** Foreign Keys ***/ /******************************************************************************/ ALTER TABLE TAB_TABL_BODY ADD CONSTRAINT FK_TAB_TABL_BODY_1 FOREIGN KEY (TABL_HEAD_CODE) REFERENCES TAB_TABL_HEAD (TABL_HEAD_CODE); /******************************************************************************/ /*** Triggers ***/ /******************************************************************************/ SET TERM ^ ; /******************************************************************************/ /*** Triggers for tables ***/ /******************************************************************************/ /* Trigger: TAB_TABL_BODY_BI */ CREATE TRIGGER TAB_TABL_BODY_BI FOR TAB_TABL_BODY ACTIVE BEFORE INSERT POSITION 0 AS BEGIN IF (NEW.TABL_BODY_CODE IS NULL) THEN NEW.TABL_BODY_CODE = GEN_ID(GEN_TABL_BODY_CODE,1); END ^ /* Trigger: TAB_TABL_HEAD_BD */ CREATE TRIGGER TAB_TABL_HEAD_BD FOR TAB_TABL_HEAD ACTIVE BEFORE DELETE POSITION 0 AS begin delete from tab_tabl_body where tabl_head_code = old.tabl_head_code; end ^ SET TERM ; ^ /******************************************************************************/ /*** Stored Procedures ***/ /******************************************************************************/ SET TERM ^ ; ALTER PROCEDURE TAB_TABL_BODY_DEL ( TABL_BODY_CODE INTEGER) AS begin delete from tab_tabl_body where (tabl_body_code = :tabl_body_code); end ^ ALTER PROCEDURE TAB_TABL_BODY_IU ( TABL_BODY_CODE INTEGER, TABL_HEAD_CODE INTEGER, TABL_BODY_NAME CHAR(14), TABL_BODY_VALT BLOB SUB_TYPE 1 SEGMENT SIZE 80, TABL_BODY_VALF FLOAT, TABL_BODY_VALI INTEGER, TABL_BODY_VALS VARCHAR(100), TABL_BODY_TYPE CHAR(1)) AS begin if (exists(select tabl_body_code from tab_tabl_body where (tabl_body_code = :tabl_body_code))) then update tab_tabl_body set tabl_head_code = :tabl_head_code, tabl_body_name = :tabl_body_name, tabl_body_valt = :tabl_body_valt, tabl_body_valf = :tabl_body_valf, tabl_body_vali = :tabl_body_vali, tabl_body_vals = :tabl_body_vals, tabl_body_type = :tabl_body_type where (tabl_body_code = :tabl_body_code); else insert into tab_tabl_body ( tabl_body_code, tabl_head_code, tabl_body_name, tabl_body_valt, tabl_body_valf, tabl_body_vali, tabl_body_vals, tabl_body_type) values ( :tabl_body_code, :tabl_head_code, :tabl_body_name, :tabl_body_valt, :tabl_body_valf, :tabl_body_vali, :tabl_body_vals, :tabl_body_type); end ^ ALTER PROCEDURE TAB_TABL_HEAD_DEL ( TABL_HEAD_CODE INTEGER) AS begin delete from tab_tabl_head where (tabl_head_code = :tabl_head_code); end ^ ALTER PROCEDURE TAB_TABL_HEAD_IU ( TABL_HEAD_CODE INTEGER, TABL_HEAD_NAME CHAR(13), TABL_HEAD_CTST TIMESTAMP, TABL_HEAD_STAT INTEGER, TABL_HEAD_TYPE INTEGER, TABL_HEAD_ACTV INTEGER, TABL_HEAD_SYST CHAR(36), TABL_HEAD_1CCO CHAR(36)) AS begin if (exists(select tabl_head_code from tab_tabl_head where (tabl_head_code = :tabl_head_code))) then update tab_tabl_head set tabl_head_name = :tabl_head_name, tabl_head_ctst = :tabl_head_ctst, tabl_head_stat = :tabl_head_stat, tabl_head_type = :tabl_head_type, tabl_head_actv = :tabl_head_actv, tabl_head_syst = :tabl_head_syst, tabl_head_1cco = :tabl_head_1cco where (tabl_head_code = :tabl_head_code); else insert into tab_tabl_head ( tabl_head_code, tabl_head_name, tabl_head_ctst, tabl_head_stat, tabl_head_type, tabl_head_actv, tabl_head_syst, tabl_head_1cco) values ( :tabl_head_code, :tabl_head_name, :tabl_head_ctst, :tabl_head_stat, :tabl_head_type, :tabl_head_actv, :tabl_head_syst, :tabl_head_1cco); end ^ SET TERM ; ^ /******************************************************************************/ /*** Descriptions ***/ /******************************************************************************/ DESCRIBE DOMAIN DOM_CHAR 'Символ'; DESCRIBE DOMAIN DOM_CODE 'Уникальный код записи'; DESCRIBE DOMAIN DOM_FLOAT 'Число с плавающей точкой'; DESCRIBE DOMAIN DOM_INT 'Целое число'; DESCRIBE DOMAIN DOM_ST100 'Строка, 100 символов'; DESCRIBE DOMAIN DOM_ST13 'Строка, 13 символов'; DESCRIBE DOMAIN DOM_ST14 'Строка, 14 символов'; DESCRIBE DOMAIN DOM_ST36 'Строка, 36 символов'; DESCRIBE DOMAIN DOM_TEXT 'Текст'; DESCRIBE DOMAIN DOM_TIMESTAMP 'Дата и время'; /******************************************************************************/ /*** Descriptions ***/ /******************************************************************************/ DESCRIBE TABLE TAB_TABL_BODY 'Значения столбцов'; DESCRIBE TABLE TAB_TABL_HEAD 'Таблицы'; /******************************************************************************/ /*** Descriptions ***/ /******************************************************************************/ DESCRIBE PROCEDURE TAB_TABL_BODY_DEL 'Значения стобцов - удаление записи'; DESCRIBE PROCEDURE TAB_TABL_BODY_IU 'Значения стобцов - изменение записи'; DESCRIBE PROCEDURE TAB_TABL_HEAD_DEL 'Таблицы - удаление записи'; DESCRIBE PROCEDURE TAB_TABL_HEAD_IU 'Таблицы - изменение записи'; /******************************************************************************/ /*** Descriptions ***/ /******************************************************************************/ DESCRIBE TRIGGER TAB_TABL_BODY_BI 'Значения столбцов - установка УКЗ'; DESCRIBE TRIGGER TAB_TABL_HEAD_BD 'Таблицы - удаление значений столбцов'; /******************************************************************************/ /*** Descriptions ***/ /******************************************************************************/ DESCRIBE GENERATOR GEN_TABL_BODY_CODE 'Значения столбцов - уникальный код записи'; DESCRIBE GENERATOR GEN_TABL_HEAD_CODE 'Таблицы - уникальный уод записи'; /* Fields descriptions */ DESCRIBE FIELD TABL_BODY_CODE TABLE TAB_TABL_BODY 'Уникальный код записи'; DESCRIBE FIELD TABL_HEAD_CODE TABLE TAB_TABL_BODY 'Код таблицы'; DESCRIBE FIELD TABL_BODY_NAME TABLE TAB_TABL_BODY 'Имя столбца'; DESCRIBE FIELD TABL_BODY_VALT TABLE TAB_TABL_BODY 'Значение - текст'; DESCRIBE FIELD TABL_BODY_VALF TABLE TAB_TABL_BODY 'Значение - число с плавающей точкой'; DESCRIBE FIELD TABL_BODY_VALI TABLE TAB_TABL_BODY 'Значение - целое число'; DESCRIBE FIELD TABL_BODY_VALS TABLE TAB_TABL_BODY 'Значение - строка, 100 символов'; DESCRIBE FIELD TABL_BODY_TYPE TABLE TAB_TABL_BODY 'Тип данных (T - текст, F - число с плавающей точкой, I - целое число, S - строка)'; DESCRIBE FIELD TABL_HEAD_CODE TABLE TAB_TABL_HEAD 'Уникальный код записи'; DESCRIBE FIELD TABL_HEAD_NAME TABLE TAB_TABL_HEAD 'Имя таблицы'; DESCRIBE FIELD TABL_HEAD_CTST TABLE TAB_TABL_HEAD 'Дата и время создания'; DESCRIBE FIELD TABL_HEAD_STAT TABLE TAB_TABL_HEAD 'Состояние (1 - изменение записи, 2 - удаление записи)'; DESCRIBE FIELD TABL_HEAD_TYPE TABLE TAB_TABL_HEAD 'Тип таблицы (1 - простая, 2 - со ссылками, 3 - требует разбора)'; DESCRIBE FIELD TABL_HEAD_ACTV TABLE TAB_TABL_HEAD 'Признак аннулирования (0 - нет, 1 - запись аннулирована)'; DESCRIBE FIELD TABL_HEAD_SYST TABLE TAB_TABL_HEAD 'Код ТП (уникальный идентификатор ТП)'; DESCRIBE FIELD TABL_HEAD_1CCO TABLE TAB_TABL_HEAD 'Код 1С'; |
|||
69
kanalex
25.09.12
✎
15:57
|
экспортируется в эту базу.
в две таблицы: HEAD и BODY |
|||
70
Jofa
25.09.12
✎
15:59
|
Дак а ты в Чарсет что подставлял?
|
|||
71
Jofa
25.09.12
✎
15:59
|
WIN1251 ?
|
|||
72
kanalex
25.09.12
✎
16:00
|
(71) да
|
|||
73
Jofa
25.09.12
✎
16:01
|
Попробуй UTF8
|
|||
74
kanalex
25.09.12
✎
16:01
|
(43) да, это лишнее.... согласен.
|
|||
75
Jofa
25.09.12
✎
16:03
|
По пробывал?
|
|||
76
Jofa
25.09.12
✎
16:07
|
ау
|
|||
77
kanalex
25.09.12
✎
16:08
|
по 50 записей в запрос:
Начали: 25.09.2012 16:05:46 Закончили: 25.09.2012 16:07:52 |
|||
78
kanalex
25.09.12
✎
16:08
|
как-то не сильно помогло
|
|||
79
MMF
25.09.12
✎
16:10
|
(74) открой для себя поле smallint (речь о колонках TABL_HEAD_STAT, TABL_HEAD_ACTV и прочия)
|
|||
80
Jofa
25.09.12
✎
16:11
|
Ты выгружаешь в Птичку или в 1Ску?
|
|||
81
kanalex
25.09.12
✎
16:11
|
из 1С в птичку
|
|||
82
kanalex
25.09.12
✎
16:11
|
обратно тоже будет, но совсем не много
|
|||
83
MMF
25.09.12
✎
17:15
|
(82) триггер TAB_TABL_HEAD_BD я бы прибил, а во внешнем ключе FK_TAB_TABL_BODY_1 поставил каскадное удаление
|
|||
84
MMF
25.09.12
✎
17:44
|
сделал маленькую тестовую прогу. Она вставляет в твои таблицы выбранное кол-во записей.
Для 100 000 записей каждого типа и ForcedWrites ON: Вставка серии целых Время вставки: 27468 Вставка серии строк Время вставки: 28249 Всего затрачено: 55717 Для тех же 100 000 и ForcedWrites Off: Вставка серии целых Время вставки: 22936 Вставка серии строк Время вставки: 25250 Всего затрачено: 48186 |
|||
85
MMF
25.09.12
✎
17:47
|
т.е. скорость вставки: 3590 записей/секунду FW On и 4149 зап/с для FW Off
Такую скорость на обычном железе получишь при использовании ВК, выкинь нафиг свое АДО |
|||
86
MMF
25.09.12
✎
17:49
|
мегасофтину можешь скачать тут http://www.onlinedisk.ru/file/950495/
|
|||
87
MMF
25.09.12
✎
17:51
|
http://www.onlinedisk.ru/file/950497/ слегка подрихтовал скрипт
|
|||
88
kanalex
25.09.12
✎
22:07
|
(85) примерно в 10 раз быстрее...
|
|||
89
Ненавижу 1С
гуру
25.09.12
✎
22:13
|
нужны вам какие-то подобия планов обмена, чтобы 150 раз не таскать одни и теже данные
|
|||
90
kanalex
25.09.12
✎
22:17
|
(89) так одни данные и не таскаются. таскаются ссылки на уже выгруженное.
|
|||
91
Jofa
26.09.12
✎
06:30
|
(85)А что такое ВК?
|
|||
92
ILM
гуру
26.09.12
✎
06:44
|
(0) А можно спросить, что за базы, и что за инфа?
Может стоит ограничить уровень детализации для консолидации. Грузить не все, а только агрегированные данные. Если пустили бы к ТЗ, то указал бы на ряд косяков в нём. |
|||
93
Jofa
26.09.12
✎
06:57
|
(92) А почему детализацию для консолидации хранят во внешней базеотдельно?
|
|||
94
kanalex
26.09.12
✎
09:19
|
(91) ВК - внешняя компонента
|
|||
95
kanalex
26.09.12
✎
09:21
|
(92) - исходные базы - сильно переделанные УТ 10.3
Грузится из них не все, конечно.... Я вообщем, спорил по некоторым моментам, но заказчик настаивает, что ему нужны все цены... за все годы, например. Ну еще там есть подобные моменты. |
|||
96
kanalex
26.09.12
✎
13:05
|
Пробуем ВК:
http://infostart.ru/public/15365/ пока не удалось подключить к 8-ке:( GameWithFire v8: GameWithFire щас попробуем... |
|||
97
MMF
26.09.12
✎
13:18
|
(96) блин, да сам напиши, не поможет тебе чужая ВК, потому как потеряешь на установке свойств и методов ВК половину выигранного времени - ILanguageExtender тормозная штука
|
|||
98
kanalex
26.09.12
✎
13:21
|
(97) да не писал я их никогда. Нет времени сейчас на это:(
|
|||
99
kanalex
26.09.12
✎
16:43
|
обратимся к параметрам...
ТекстЗапроса = "execute procedure TAB_TABL_HEAD_IU(?, ?, ?, ?, ?, ?, ?, ?);"; КомандаАДО.CommandText = ТекстЗапроса; Параметр1 = КомандаАДО.CreateParameter("TABL_HEAD_CODE",3,1,,2); Параметр2 = КомандаАДО.CreateParameter("TABL_HEAD_NAME",8,1,,"А"); Параметр3 = КомандаАДО.CreateParameter("TABL_HEAD_CTST",7,1,,ТекущаяДата()); Параметр4 = КомандаАДО.CreateParameter("TABL_HEAD_STAT",3,1,,TABL_HEAD_STAT); Параметр5 = КомандаАДО.CreateParameter("TABL_HEAD_TYPE",3,1,,TABL_HEAD_TYPE); Параметр6 = КомандаАДО.CreateParameter("TABL_HEAD_ACTV",3,1,,TABL_HEAD_ACTV); Параметр7 = КомандаАДО.CreateParameter("TABL_HEAD_SYST",8,1,,тт_ПустаяСсылка); Параметр8 = КомандаАДО.CreateParameter("TABL_HEAD_1CCO",8,1,,тт_ПустаяСсылка); КомандаАДО.Parameters.Append(Параметр1); КомандаАДО.Parameters.Append(Параметр2); КомандаАДО.Parameters.Append(Параметр3); КомандаАДО.Parameters.Append(Параметр4); КомандаАДО.Parameters.Append(Параметр5); КомандаАДО.Parameters.Append(Параметр6); КомандаАДО.Parameters.Append(Параметр7); КомандаАДО.Parameters.Append(Параметр8); Рекордсет = КомандаАДО.Execute(); |
|||
100
kanalex
26.09.12
✎
17:23
|
Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done
На второй записи... |
|||
101
ILM
гуру
26.09.12
✎
18:32
|
(95) Цены за все года? Надеюсь хоть продажные?
|
|||
102
kanalex
26.09.12
✎
21:03
|
(101) Да, но это тоже не мало:)
При номенклатуре с 10-к тыс. позиций |
|||
103
kanalex
26.09.12
✎
22:19
|
(101) почти 90 тыс позиций в запросе к справочнику номенклатуры:)
|
|||
104
kanalex
27.09.12
✎
12:45
|
ТекстЗапроса = "execute procedure TAB_TABL_HEAD_IU(" + HeadIDString + ", '" + TableNameString_proc + "', current_timestamp, " + TABL_HEAD_STAT + ", " + TABL_HEAD_TYPE + ", " + TABL_HEAD_ACTV_proc + ", '" + TABL_HEAD_SYST + "', '" + TABL_HEAD_1CCO + "')";
Вот так отработал цикл. По другому пока не получилось:( По времени выигрыша нет. На 1000 записях в запросе выигрыш несколько секунд. Это можно считать погрешностью. |
|||
105
kanalex
27.09.12
✎
12:56
|
Для а = 100000 По 100900 Цикл
ТекстЗапроса = "execute procedure TAB_TABL_HEAD_IU(?, ?, current_timestamp, ?, ?, ?, ?, ?);"; КомандаАДО.CommandText = ТекстЗапроса; Параметр1 = КомандаАДО.CreateParameter("TABL_HEAD_CODE",3,1,,а); Параметр2 = КомандаАДО.CreateParameter("TABL_HEAD_NAME",8,1,,"А"); Параметр3 = КомандаАДО.CreateParameter("TABL_HEAD_STAT",3,1,,TABL_HEAD_STAT); Параметр4 = КомандаАДО.CreateParameter("TABL_HEAD_TYPE",3,1,,TABL_HEAD_TYPE); Параметр5 = КомандаАДО.CreateParameter("TABL_HEAD_ACTV",3,1,,TABL_HEAD_ACTV); Параметр6 = КомандаАДО.CreateParameter("TABL_HEAD_SYST",8,1,,тт_ПустаяСсылка); Параметр7 = КомандаАДО.CreateParameter("TABL_HEAD_1CCO",8,1,,тт_ПустаяСсылка); КомандаАДО.Parameters.Append(Параметр1); КомандаАДО.Parameters.Append(Параметр2); КомандаАДО.Parameters.Append(Параметр3); КомандаАДО.Parameters.Append(Параметр4); КомандаАДО.Parameters.Append(Параметр5); КомандаАДО.Parameters.Append(Параметр6); КомандаАДО.Parameters.Append(Параметр7); Попытка Рекордсет = КомандаАДО.Execute(); Исключение Сообщить(ТекстЗапроса + " - " + а); Предупреждение("Не получилось выполнить запрос в таблицу HEAD!" + " - " + ОписаниеОшибки()); Отказ = Истина; Возврат; КонецПопытки; КонецЦикла; такой тест по-прежнему выдает ошибку на втором шаге цикла:( |
|||
106
kanalex
27.09.12
✎
15:41
|
ТекстЗапроса = "execute procedure TAB_TABL_HEAD_IU(?, ?, current_timestamp, ?, ?, ?, ?, ?);";
Если ОбъектADO_proc.Parameters.Count > 0 Тогда Параметр1 = HeadIDString; Параметр2 = TableNameString_proc; Параметр4 = TABL_HEAD_STAT; Параметр5 = TABL_HEAD_TYPE; Параметр6 = TABL_HEAD_ACTV_proc; Параметр7 = TABL_HEAD_SYST; Параметр8 = TABL_HEAD_1CCO; Иначе Параметр1 = ОбъектADO_proc.CreateParameter("TABL_HEAD_CODE",3,1,,HeadIDString); Параметр2 = ОбъектADO_proc.CreateParameter("TABL_HEAD_NAME",8,1,,TableNameString_proc); Параметр3 = ОбъектADO_proc.CreateParameter("TABL_HEAD_STAT",3,1,,TABL_HEAD_STAT); Параметр4 = ОбъектADO_proc.CreateParameter("TABL_HEAD_TYPE",3,1,,TABL_HEAD_TYPE); Параметр5 = ОбъектADO_proc.CreateParameter("TABL_HEAD_ACTV",3,1,,TABL_HEAD_ACTV_proc); Параметр6 = ОбъектADO_proc.CreateParameter("TABL_HEAD_SYST",8,1,,TABL_HEAD_SYST); Параметр7 = ОбъектADO_proc.CreateParameter("TABL_HEAD_1CCO",8,1,,TABL_HEAD_1CCO); ОбъектADO_proc.Parameters.Append(Параметр1); ОбъектADO_proc.Parameters.Append(Параметр2); ОбъектADO_proc.Parameters.Append(Параметр3); ОбъектADO_proc.Parameters.Append(Параметр4); ОбъектADO_proc.Parameters.Append(Параметр5); ОбъектADO_proc.Parameters.Append(Параметр6); ОбъектADO_proc.Parameters.Append(Параметр7); КонецЕсли; ОбъектADO_proc.CommandText = ТекстЗапроса; Попытка Рекордсет = ОбъектADO_proc.Execute(); Исключение Сообщить(ТекстЗапроса); Предупреждение("Не получилось выполнить запрос в таблицу HEAD!" + " - " + ОписаниеОшибки()); Отказ = Истина; Возврат; КонецПопытки; Вот как должно быть! Почти работает.... |
|||
107
kanalex
27.09.12
✎
18:13
|
Теперь почему-то на втором шаге цикла вылетает из-за отсутствия внешнего ключа при добавлении записи во второй таблице...
Странно:( |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |