Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2005.11.27;
Скачать: [xml.tar.bz2];

Вниз

Проблема переноса данных из одной БД в другую   Найти похожие ветки 

 
Alex--   (2005-10-14 09:41) [0]

Проблема состоит в замедлении копирования таблицы после 200 т.з. до 1 записи в секунду. Всего в таблице 600 т.з.(8 столбцов - integer). IB6.5. Загрузка проца 50%. Памяти 50%.

Используются компоненты: (BDE) 2 DataBase и 2 Query и 1 UpdateSQL.

Способ копирования: Подключаем базу источник (данные) и базу приемник (пустая). Открываем таблицу в Query (источник)
и таблицу в Query (приемник). Прогоняем строку источника - генерируем текст SQL, кидаем его в UpdateSQL. Делаем приемник Query.Post; Query.ApplyUpdates;

Сначала копирование проходит бодро, но после 200 т.з. становится грустно. С одной транзакцией на все изменения по таблице тот же результат.
Размер страницы БД делал и 4096 и 8192.
Способ бэкапа и восстановки данных проходит тоже долго.
Можно порекомендовать другой способ слива данных.


 
Sergey13 ©   (2005-10-14 09:46) [1]

1. Нафига вообще перегонять?
2. Как часто надо перегонять?
3. Нафига "кидаем его в UpdateSQL."? Может ты и в грид все выводишь?
4. Как фиксируешь вставку?


 
Alex--   (2005-10-14 10:02) [2]

>1. Нафига вообще перегонять?
Необходимо делать так. Раскрытие этого вопроса повлечет дискусию не относящуюся к вопросу.

>2. Как часто надо перегонять?
Довольно редко. Но процесс копирования должен проходить не 4 суток.

>3. Нафига "кидаем его в UpdateSQL."? Может ты и в грид все выводишь?
Сделано для универсальности. Софтинка предпологает не только копирование данных. Компоненты отображения данных не использую.

>4. Как фиксируешь вставку?
Если правильно понял твой вопрос то:
Query.Post;
Query.ApplyUpdates;


 
ANB ©   (2005-10-14 10:13) [3]

1. Вообще то лучше insert ... select.
2. Если уж приспичило через клиента - лучше через 2 квери - одной доставать данные, в другой - присваивать параметры в заранее сгенеренный SQL и выполнять. Можно еще препарировать для скорости (иногда мешает).
3. Замедление скорее всего из-за переполнения памяти начинается, так как кверя хранит в оперативке все ранее выбранные строки. Нужно это ликвидировать. Для IB - не знаю как, в DOA есть компонент, не являющийся дэйтасетом. Возможно, можно попробовать включить Unidirectional.
4. Использовать BDE для доступа к IB да еще когда нужна высокая скорость я бы не стал.
5. Полезно еще в целевой таблице посрубать индексы и триггера.


 
Sergey13 ©   (2005-10-14 10:34) [4]

2[2] Alex--   (14.10.05 10:02)
>Сделано для универсальности.
В чем тут универсальность то? Надо просто IBSQL с параметрами выполнять. Зачем тебе 2 одинаковых набора на клиенте?

>4
Комитишь когда? Желательно записей через 500-1000 (можно поподбирать).

Можно, если юзаешь БДЕ почитать про гетерогенные запросы и сделать все одним запросом Insert from Select


 
Alex--   (2005-10-14 10:52) [5]

Универсальность заключается в использовании как баз IB так и Oracle.
(Пока вариант с ораклом не риходилось попробывать).

>Можно, если юзаешь БДЕ почитать про гетерогенные запросы и сделать все одним запросом Insert from Select.

Такой запрос в самом IB можно сгенерить и выполнить одним скриптом.
Но ситуация похожа - выполняется, но долго.


 
ANB ©   (2005-10-14 10:58) [6]


> Такой запрос в самом IB можно сгенерить и выполнить одним
> скриптом.
> Но ситуация похожа - выполняется, но долго.

Значит точно - в целевой таблице индексы и/или триггера тормозят.


 
Sergey13 ©   (2005-10-14 11:04) [7]

2[5] Alex--   (14.10.05 10:52)
>Универсальность заключается в использовании как баз IB так и Oracle.
Ну тогда не IBSQL а простой Ткверик. Только не Select-овый с UpdateSQL, а просто ему в SQL Update напиши. Суть - не формировать на клиенте второй набор данных.

>Такой запрос в самом IB можно сгенерить и выполнить одним скриптом.
А у тебя точно 2 БД, а не 2 таблицы в одной БД?


 
Alex--   (2005-10-14 11:09) [8]

БД естессно 2е. А вешается копинг на таблице с 600 т.з.
Копирование проходят все таблицы последовательно, причем бодро(небольшие).


 
Alex--   (2005-10-14 11:12) [9]


> Значит точно - в целевой таблице индексы и/или триггера
> тормозят.

Так а чо до 200 т.з. летаем, а потом грустим?


 
Desdechado ©   (2005-10-14 11:12) [10]

я бы сделал так:
1. читаю набор из первой БД
2. формирую параметрический INSERT
3. открываю транзакцию
4. пробежкой по первому набору заполняю параметры INSERT, и выполняю его (не через UpdateSQL!)
5. закрываю транзакцию

PS вполне возможно, что в одной транзакции это со временем будет выполняться все медленнее и медленнее. Это происходит от накопления информации для отката транзакции. Если целостность данных контролировать не надо, до можно коммитить каждую запись или небольшими пачками (НП, по 1000 штук) - найти компромисс легко.


 
Sergey13 ©   (2005-10-14 11:14) [11]

2[8] Alex--   (14.10.05 11:09)
>БД естессно 2е.
А как тогда понять
"Такой запрос в самом IB можно сгенерить"?
Insert into BD1.Table1 Select * from BD2.Table1
Это гетерогенный запрос по 2 БД сразу. БДЕ такое может. Оракл тоже может. ИБ - вроде нет.


 
Alex--   (2005-10-14 11:21) [12]

Да Sergey13  я непонял вопроса. Тогда имел ввиду IB генерит скрипт с данными типа INSERT INTO fckTable () VALUES(). И этот скрипт пробывал прогонять в консоли на базу приемник - долго.


 
Desdechado ©   (2005-10-14 12:13) [13]

быстрее скрипта ничего не будет
иногда в нем стоит вставлять commit


 
Seg   (2005-10-14 12:21) [14]

Это происходит от накопления информации для отката транзакции

Вот здесь написан правильный ответ.

в целевой таблице индексы

И это тоже надо учесть, т.е. удалить все индексы в целевой таблице.


 
Desdechado ©   (2005-10-14 12:24) [15]

удалить индексы - это жестко
достаточно сделать INACTIVE


 
Alex--   (2005-10-14 12:26) [16]

Прочитал статейку про Гетерогенные запросы на BDE
http://www.delphiworld.narod.ru/base/bde_architecture2.html

по их примеру пишу в Query

select x.Name FROM ":A:dc" x, ":B:dc" z

A,B - как я понял внутренние алиасы баз
dc - таблица которая присутствует в обоих базах IB.

Выполняем - итог "Operation not applicable".

>быстрее скрипта ничего не будет
иногда в нем стоит вставлять commit

Копирование данных делается на стороне множества заказчиков, не квалифированными сотрудниками


 
Alex--   (2005-10-14 12:30) [17]

>Это происходит от накопления информации для отката транзакции
Транзакцию не коплю. Комит проходит для каждой записи.

Скорость падает после 200 т.з


 
Desdechado ©   (2005-10-14 12:31) [18]

>Копирование данных делается неквалифированными сотрудниками
Что мешает выгружать скрипт автоматически, сохранить его во временный буфер и скормить поставляемой с сервером программе заливки данных?
И все это нажатием одной кнопки в твоей программе...


 
Desdechado ©   (2005-10-14 12:33) [19]

коммит после каждой записи тоже сильно тормозить может (в общем, а не "после 200тыс.")
ищи компромисс числа записей и числа коммитов


 
ANB ©   (2005-10-14 12:47) [20]


> Скорость падает после 200 т.з
- не в коммите дело. Кстати, пакетные коммиты дают не очень большой прирост скорости. Индексы отрубил ?


 
Seg   (2005-10-14 12:51) [21]

На Оракле до 1 000 000 записей копируется одной транзакцией на ура.
Не 4 суток, а часа 2-4.
Если 600 000 записей копируются 4 суток, то дело может и не в серваке, а в сети или на клиенте...


 
Alex--   (2005-10-14 12:53) [22]

Щас буду пробывать отрубание индексов. Результаты сообщу.
Можно и генерацию скрипта с комитом попробывать.


 
Digitman ©   (2005-10-14 12:55) [23]


> Alex--  


поставь ту же версию  IB-совместимого сервера на линуховый хост (если таковая под Линух имеется) и приятно удивись - при абсолютно тех же условиях "тормоза" при таком массированной вставке ощутимо снизятся

клиента твоего, естественно, не рассматриваем, где бы и под кем бы он у тебя ни работал.

ну а в целом и общем основные рекомендации были даны правильные :

1. перед массированной вставкой выключай целевые индексы/триггеры

2. не дроби транзакцию на кучу мелких, вплоть до несуразности, когда на одну запись - одна транзакция


 
Alex--   (2005-10-14 12:55) [24]

>На Оракле до 1 000 000 записей копируется одной транзакцией на ура.
>Не 4 суток, а часа 2-4.
На оракле такое не пробывал. Просто предпологается в будущем.
Уверен сним проблем то и небудет.


 
Seg   (2005-10-14 13:06) [25]

Самое долгое копирование, которое мне приходилось делать на Оракле - 135 000 000 записей.
Процесс длился 3 суток, правда копирование производилось на одном сервере в пределах одной схемы.

Загрузка из дампа 50 000 000 записей происходила за 1.5-2 часа.

Правда на хорошем 4-х процессорном серваке.


 
Desdechado ©   (2005-10-14 13:21) [26]

2 Seg
для корректной оценки приведенных цифр неплохо бы указывать и количество таблиц, и размер записей, и много еще чего...


 
Sergey13 ©   (2005-10-14 13:32) [27]

2[26] Desdechado ©   (14.10.05 13:21)
Приведенные цифры вообще ни о чем не говорят и к сабжу имеют очень далекое отношение. ИМХО


 
Seg   (2005-10-14 13:35) [28]

Я не претендую на точность до грамма.
Просто привел порядок цифр. На фоне таких объемов 600 000 записей за 4 суток как-то заставляет задуматься.


 
Sergey13 ©   (2005-10-14 13:39) [29]

2[28] Seg   (14.10.05 13:35)
> На фоне таких объемов 600 000 записей за 4 суток как-то заставляет задуматься.
Так автор и задумался. Даже ветку создал, где советов спрашивает. 8-)


 
Sergey13 ©   (2005-10-14 13:48) [30]

2 Alex--
В ИБ можно еще попробовать через внешнюю таблицу. Универсальность правда лесом идет, но как вариант.


 
Anatoly Podgoretsky ©   (2005-10-14 14:19) [31]

Seg   (14.10.05 13:35) [28]
А зачем ты за 4 суток берешь, надо как минимум 125000*365*N


 
Alex--   (2005-10-17 11:21) [32]

Удаление индексов ожидаемого результата не принесло. Все постарому, скорость копирования падает. IBServer грузит систему на 80%. ХЗЧ.

>для корректной оценки приведенных цифр неплохо бы указывать и >количество таблиц, и размер записей,

Всего таблиц 50. Не более 600 записей в каждой. Копируются без проблем.
Настройки IB по умолчанию.
Проблемная таблица:
CREATE TABLE VHH (
   DCID SMALLINT NOT NULL,
   OBJID SMALLINT NOT NULL,
   DEVID SMALLINT NOT NULL,
   JOINID SMALLINT NOT NULL,
   CHANID SMALLINT NOT NULL,
   STAMP DATE NOT NULL,
   VAL NUMERIC (18, 5),
   RELIABLE SMALLINT);
/* Primary keys definition */
ALTER TABLE VHH ADD PRIMARY KEY (DCID, OBJID, DEVID, JOINID, CHANID, STAMP);
/* Foreign keys definition */
ALTER TABLE VHH ADD CONSTRAINT VHH_FOREIGN FOREIGN KEY (DCID, OBJID, DEVID, JOINID, CHANID) REFERENCES CHANNELS (DCID, OBJID, DEVID, JOINID, CHANID) ON DELETE CASCADE ON UPDATE CASCADE;


Количество записей 600 000.

>и много еще чего...
Пиши конкретно, укажу.

>На фоне таких объемов 600 000 записей за 4 суток как-то заставляет задуматься.

Чем успешно и занимаемся :)
Такое время ни кто не ждал. Тут или я делаю не правильно (вероятнее) или сервер.
200 т.з копим на ура. 600 - 200 = 400 т.з.
копируется ~ 1 запись в секунду.
400 000 / 60 / 60 / 24 = 4.62 суток.


 
Desdechado ©   (2005-10-17 11:55) [33]

индексы точно удалил?
а PK и FK? В FB для них индексы создаются автоматически, тем паче такой длинный ключ. Лучше грохнуть PK и FK, а после заливки создать заново.


 
Alex--   (2005-10-17 12:02) [34]

>индексы точно удалил? а PK и FK?

Точно. Не отключил, а удалил. И PK и FK.
Чеки и процедуры удалил навсякий.


 
Sergey13 ©   (2005-10-17 12:09) [35]

2 [34] Alex--   (17.10.05 12:02)
А что ты еще попробовал кроме индексов? UpdateSQL выкинул?


 
Alex--   (2005-10-17 12:25) [36]

Только индексы, ка самый быстрый вариант. Буду копать загрузку из скрипта с данными, с комитом пакета данных. Ну и без UpdateSQL попробую.


 
Sergey13 ©   (2005-10-17 12:33) [37]

2[36] Alex--   (17.10.05 12:25)
Самый быстрый вариант - это выбирать не всю исходную таблицу, а ее часть. После записи части коммит и выборка следующей части. Так до упора. С размером части можно экспериментировать. И UpdateSQL конечно выкинуть.


 
Danilka ©   (2005-10-17 14:02) [38]

Первым делом надо выкинуть UpdateSQL.
Для вставки использовать только запрос INSERT INTO... с параметрами.
До цикла с инсертами сделать ему prepare.
В самом цикле только подставлять параметры и выполнять запрос.

Если БДЕ выбран только для универсальности, чтоб можно было и к ИБ и к Ороклу цепляться, то, думаю, следует присмотреться к ДБЭкспресс-у, т.к. у него некешируемые однонаправленные компоненты доступа, в отличие от БДЕ, у которого все 600тыс.записей, после прохода до конца датасета, будут сидеть у тебя в памяти до тех пор, пока не закроешь запрос.
Если универсальность нафиг не нужна - используй для чтения IBX-компоненты, конкретно IBSQL, который также не кеширует записи.
Но самый главный источник тормозов, на мой взгляд, это использование UpdateSQL.


 
Danilka ©   (2005-10-17 14:10) [39]

ой, блин, тема-то еще пятничная.. и за все это время аффтор сумел тока индексы отключить?
вот-же люди ленивые пошли, им легче тупо смотреть как по 1-й записи в секунду в базу пишецца, чем попробовать то, что посоветовали три дня назад...



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2005.11.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.015 c
1-1131006645
TUser
2005-11-03 11:30
2005.11.27
Уничтожение вложенных объектов


1-1130933195
s_t_d
2005-11-02 15:06
2005.11.27
QReport в Delphi-7


2-1131643524
The One
2005-11-10 20:25
2005.11.27
Ordinal type required


14-1131374953
oldman
2005-11-07 17:49
2005.11.27
Опрос. Кто вам мешает жить?


5-1103495421
k@rt
2004-12-20 01:30
2005.11.27
Перерисовка TPageControl





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский