![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Импорт из *.dbf в FireBird [D7, FireBird 2.0]
MZ © (2007-05-16 14:52:00)Может кто подскажет... Нужно сделать импорт из dbf таблицы в FireBird. Пользуюсь FIBPlus. Делаю так: С помощью BDE связаваюсь с исходными таблицами и тупо присваиваю значения - FIBDataSet1.FN('Принимающее поле').asString:=Query1.FieldByName('Исходное поле').AsString
Но работает медленно. Может есть более оптимальный способ это сделать...
kaif (2007-05-18 22:54:00) [1]Я недавно делал импорт 1.5 млн записей в Firebird 1.5.
Одинстарт вначале и одинкоммит в конце. Изначально таблица пустая. Никакого видимого замедления при добавлении новых записей в процессе импорта не наблюдалось. (Каждые 100 записей обновляю ProgressBar). Весь импорт занимает около часа. Для соединения с DBF использовал OLE DB Provider for Microsoft Visual FoxPro.
А вообще я как правило всегда сталкивался с постепенным ощутимым замедлением при вставке. Раньше я всегда применял COMMIT на каждые 100 записей. Впервые (причем совершенно случайно!) попробовал один общий коммит на полтора миллиона. Все отлично. Возможно проблема возникала обычно из-за сочетания частого коммита с ForcedWrites.
Хотя точно сказать не могу - так как этот импорт заработал, уже сильно вникать не стал.
:)
Но предлагаю попробовать общий коммит на весь импорт.
Если замедление исчезнет, то почему бы нет?
:)
Mike Kouzmine (2007-05-18 20:29:00) [2]В 6 дельфи был комплонент в бде назывался TDataPump ввроде. Там можно настраивать - добавлять, заново и т.д. Какие поля куда. Куда девать записи не вставленные по любым причинам... Для копирования удобен, но требует БДЕ
ANB (2007-05-17 12:25:00) [3]
> Jan1 (16.05.07 19:22) [25]
Хех. Для инсерта в хранимке на чистую таблицу это может и существенно.
Однако в условиях :
1. Каждый инсерт приезжает по одному с клиента
2. Кроме как в мс скл нужно синхронно писать еще и лог в оракл (обрабатывая при этом ошибки, чтобы процесс не прерывался)
3. Достав очередную запись из оракла попрыгать вокруг с нее с бубном, т.к. в исходном виде она укладываться не хочет (минимум - заменить ID и ссылки)
4. На таблицу навешены куча индексов и триггеров и срубать их нельзя
5. Перед вставкой записи нужно убедиться, что такой еще нету (причем на констрейнты полагаться нельзя, т.к. проверка заумная)
вот в таких условиях выигрыш на коммитах практически незаметен :)
Jan1 (2007-05-16 19:22:00) [4]в принципе нагляднее будет строку
select 1000.0 / ((1.0*datediff( ms, @t, getdate())) / 1000.0)
на
select datediff( ms, @t, getdate())
Jan1 (2007-05-16 19:12:00) [5]пример, не мой.
Jan1 (2007-05-16 19:08:00) [6]
> С коммитом на каждую запись перекачка шла двое суток и на
> каждую 1000 - примерно столько же.
Проверь:
use Northwind
go
SET ARITHABORT off
go
create table a ( id int, flag int )
GO
set nocount on
declare @i int, @t datetime
select @i = 0, @t = getdate()
while @i < 1000 begin
insert into a (id, flag ) select @i, @i
select @i = @i + 1
end
select 1000.0 / ((1.0*datediff( ms, @t, getdate())) / 1000.0)
GO
drop table a
GO
create table a ( id int, flag int )
GO
set nocount on
declare @i int, @t datetime
select @i = 0, @t = getdate()
begin tran
while @i < 1000 begin
insert into a (id, flag ) select @i, @i
select @i = @i + 1
end
commit
select 1000.0 / ((1.0*datediff( ms, @t, getdate())) / 1000.0)
GO
drop table a
GO
результат:
-----------------------------------
2463.0541871921182266009852
-----------------------------------
30303.0303030303030303030303
ANB (2007-05-16 18:53:00) [7]
> как засекал?
Часами. С коммитом на каждую запись перекачка шла двое суток и на каждую 1000 - примерно столько же. Только еще грабли с ошибками собирать пришлось. В конце концов плюнул, поставил коммит на каждую запись (точнее выкинул старт транзакции и все с ним связанное), выбирая надежность минимальному приросту скорости.
Jan1 (2007-05-16 17:40:00) [8]
> У МС - вообще эффекта практически нету. Специально засекал
> при конвертации.
как засекал?
ANB (2007-05-16 17:24:00) [9]
> а у МС
У МС - вообще эффекта практически нету. Специально засекал при конвертации.
Loginov Dmitry (2007-05-16 16:50:00) [10]При использовании TpFIBQuery скорость инсертов реально увеличивается, причем как минимум в 3 раза. А вот эффекта от Prepared че-то незаметно.
Jan1 (2007-05-16 16:45:00) [11]
> Я вот думаю, что инсерт навигационными методами несколько
> помедленнее прямого скл инсерта. Особливо если запрос с
> параметрами и его заранее препарировать.
зачему тут чего-то думать, просто надо глянуть внутрености плюсов.
> Кстати, по опыту, играние коммитами дает мало выигрыша.
> В оракле прирост скорости - несколько процентов, зато имеем
> геморрой с обработкой процесса.
может это у Оракла, а у МС и ФБ это дает существенны прирост.
ANB (2007-05-16 16:41:00) [12]
> а ты думаешь FIBPlus их как-то обходит? :)
Я вот думаю, что инсерт навигационными методами несколько помедленнее прямого скл инсерта. Особливо если запрос с параметрами и его заранее препарировать. ИМХО - качалки типа DataPump фактически так и делают.
Кстати, по опыту, играние коммитами дает мало выигрыша. В оракле прирост скорости - несколько процентов, зато имеем геморрой с обработкой процесса.
MZ (2007-05-16 15:54:00) [13]Точно... Не выполнялось условие if Query1.Fieds[5].IsNull
сделал if (Query1.Fieds[5].IsNull) or (Query1.Fieds[5].asString='') then ... -так работает
Jan1 (2007-05-16 15:50:00) [14]
> так как же мне узнать какую запись пропускать?
почему запись? поле. пропускать его заполнение, оно ляжет в базу null. или используй у полей свойство Value, для БЛОБа юзай Assign.
Jan1 (2007-05-16 15:48:00) [15]
> Чтоб скорость не падала, имхо, следует использовать запросы
> с параметрами.
а ты думаешь FIBPlus их как-то обходит? :)
Loginov Dmitry (2007-05-16 15:37:00) [16]> Еще такой вопрос. Значения я присваиваю в цикле, и у меня
> возникла такая проблема - если в исходной таблице нет значения,
> то FIBDataSet оставляет предидущее значение поля, боролся
> так
> if Query1.Fields[5].IsNull then FIBDataSet.FN('Принимающее
> поле').AsString:=' - '
> else FIBDataSet.FN('Принимающееполе').AsString:=Query1.Fields[5].AsS
> tring; Q
> Не помогает. Подскажите как быть
Так попробуй:
if not Query1.Fieds[5].IsNull then
FIBDataSet.FN('Принимающееполе').Assign(Query1.Fieds[5]);
MZ (2007-05-16 15:35:00) [17]
> пропускать
>
Как это пропускать? Наскока я понял уменя не работает if Query1.Fields[5].IsNull
так как же мне узнать какую запись пропускать?
Loginov Dmitry (2007-05-16 15:33:00) [18]> Лучше используй TDBF версии 6.9 или выше и BDE нафиг не
> нужен и скорость быстрей + использую, то что посоветовал
> Jan1
DBF здесь непричем. Скорость падает при добавлении записей в табличку FireBird. Чтоб скорость не падала, имхо, следует использовать запросы с параметрами.
Jan1 (2007-05-16 15:32:00) [19]
> Подскажите как быть
пропускать
MZ (2007-05-16 15:25:00) [20]Еще такой вопрос. Значения я присваиваю в цикле, и у меня возникла такая проблема - если в исходной таблице нет значения, то FIBDataSet оставляет предидущее значение поля, боролся так
if Query1.Fields[5].IsNull then FIBDataSet.FN('Принимающее поле').AsString:=' - '
else FIBDataSet.FN('Принимающееполе').AsString:=Query1.Fields[5].AsString; Q
Не помогает. Подскажите как быть