Форум » [x]Harbour » Как переписать записи из одной БД в другую БД ? » Ответить

Как переписать записи из одной БД в другую БД ?

Andrey: Всем привет ! Столкнулся с проблемой, очень медленно идет запись из одной БД в другую БД. Т.е. когда меняешь структуру БД и имеешь 200-300 полей в базе при кол-ве записей: 150 000, то процесс обновления структуры становиться довольно утомительным занятием. Да еще нужен "бегунок" чтоб пользователь не подумал, что задача "висит" ! Вывод на экран тоже медленная операция ? Может не каждую запись отражать, а через 10% ? Можно ли как то ускорить этот процесс ? Задача на хХарборе, терминал gtwvt !

Ответов - 41, стр: 1 2 3 All

santy: При таком количестве полей и записей однозначно будет медленно работать. Нужно уменьшать количество полей. Разбить на меньшие таблицы, провести нормализацию.

Dima: santy Андрей на это не пойдет , где то была тема где он это изложил.

PSP: Andrey пишет: Может не каждую запись отражать, а через 10% ? Можно не только прогресс-бар рисовать, а и время затраченное/оставшееся. Чтобы юзеру не скучно было... :) Оставшееся время легко подсчитать.


Dima: PSP пишет: Чтобы юзеру не скучно было... :) Можно еще тетрис (исходники есть) запускать до окончания процесса :)

santy: Уменьши количество записей, старые в архивную базу. Можна создать основную таблицу с которой ты постоянно работаешь где будут рабочие данные и архивную базу. 2. Создать вторую базу объединить две базы по уникальному полю, и добавлять поля в новую базу и соответсвенно записи. Постоянно менять структуру базы - это не очень хороший вариант. При увеличении количества записей и полей, скорость записи данных будет падать постоянно.

Andrey: santy пишет: Можна создать основную таблицу с которой ты постоянно работаешь где будут рабочие данные и архивную базу. Это основная база ! В архив уже лишнее затолкал. santy пишет: Постоянно менять структуру базы - это не очень хороший вариант. А как быть, если нужны дополнительные поля ? Например БД-Договоров, карточка полей состоит из 250 граф, и вот еще потребовалось дополнительные графы ! Тут уж хочешь не хочешь, а добавлять и менять структуру базы придется ! Про запас создать, тоже не дело.

Andrey: PSP пишет: Можно не только прогресс-бар рисовать, а и время затраченное/оставшееся. Чтобы юзеру не скучно было... :) Оставшееся время легко подсчитать. Как, я уже пробовал, не смог ? Вывожу только: прошло времени - ххх сек.

Andrey: Есть вариант с APPEND FROM - он быстрей работает, но там бегунок прикрутить я не смог. Может кто смог ? И там я не знаю как сделать "обработку" исключительной ситуации - когда в БД "мусор" записался. Все утилиты DBU, DBUCDX, BDBFS, DbfDesk - "вылетают" при обработки такой базы. А при моем (простом) копировании, я такие записи пропускаю и записываю их номера в журнал-ошибок !

petr707: Добавить к APPEND FROM FOR xxxxx() .... begunok_open() APPEND FROM FOR begunok_say() .and. analyz() begunok_close() .... Function analiz() Local ret:=.f. if valid_rec() // проверка записи БД источника ret=.t. else out_log() // ret:=.f. endif return ret

Andrey: petr707 пишет: Добавить к APPEND FROM FOR xxxxx() Идею понял, спасибо БОЛЬНОЕ за отклик ! Но не совсем понятно, куда выводить тек.кол-во записи и общее кол-во записи ? Можно ли расширить пример ? Заранее спасибо !

Zakrzevky: Есть почти готовый пример. Правда делал для COPY TO, но ведь какая разница. Немного изменил, но что-то в этом роде.... k:=0 l:= Kdonor->(LastRec()) // или еще как-нибудь посчитать // инициализация индикатора D_IRWait(x+5,y+1,"отбор и поиск данных ",l,k,40,; Menucolor,MenuHcolor,.F.,.F.,.F.) // копирование информации @ x+1,y+30 say "всего: " +Str(l,6) // изменено для примера! @ x+2,y+28 say "прочитано: "+Str(k,6) copy to (WORK+"wrk401r") rest for ChangeDate(m->maildate,m->mailTime,@k) Function ChangeDate(maildate,mailTime,k) Local mDate,ret k++ // !!! D_IRWait(,,"отбор и поиск данных ",,k,40,; Menucolor,MenuHcolor,.F.,.F.,.F.) // это ... уже не важно mDate := if(Empty(Kdonor->DATEL),Kdonor->DATEF,Kdonor->DATEL) ret := ; mDate > maildate.or.(mDate = maildate.and.; TimeToSec(mailTime) < TimeToSec(Kdonor->TIMEL)) Return(ret) // собственно и есть индикатор и в этом окне можно показывать // соотношение всего / прочитано FUNCTION D_IRWait(Lin,Col,Text,Maxps,Pos,Li,Lc,Hc,Shad,Rest,Soun) STATIC nIntens,nBln,Ucolor,Scr STATIC eFirst:=.T.,Lcolor,HColor STATIC nOld,nProc,Txt,Sn,Sh,Rs STATIC nT,nL,nR,nB,Lind,MaxPos LOCAL Ocolor:=SETCOLOR(),n,prc,l // закрытие "змейки" IF PCOUNT()=0 IF Rs RESTSCREEN(nT-1,nL-1,nB+2,nR+2,Scr) ENDIF nOld:=nProc:=0 ; eFirst:=.T. IF Sn TONE (50,1) ;TONE (200,1); TONE (100,2); TONE (150,1) ENDIF SET(_SET_INTENSITY,nIntens) ; SETBLINK(nBln) Lcolor:=HColor:=Ucolor:=Scr:=nIntens:=nOld:=nProc:=Txt:=NIL nT:=nL:=nR:=nB:=MaxPos:=NIL SETCOLOR(Ocolor) RETURN (NIL) ENDIF // первое вхождение IF eFirst Maxpos := IF( Maxps==NIL,1,MaxPs) Pos := IF( Pos==NIL,0,Pos) Lind := IF( Li==NIL,20,IF(Li< 20, 20 , Li ) ) Txt := Text LColor := IF(LC==NIL,SETCOLOR(),LC) HColor := IF(HC==NIL,"*"+SETCOLOR(),HC) Sh := IF(Shad==NIL,.T.,Shad) Rs := IF(Rest==NIL,.T.,Rest) Sn := IF(Soun==NIL,.T.,Soun) eFirst:=.F. ; nOld:=0 ; nProc:=0 SET(_SET_INTENSITY,.T.) SETBLINK(.F.) SETCOLOR(LColor) Ucolor:=LEFT(HColor,AT(",",Hcolor)-1)+"*" nT:=IF(Lin==NIL,INT(MAXROW()/2-2),Lin) nL:=IF(Col==NIL,INT((MAXCOL()-Lind-6)/2),Col) nB:=IF(Lin==NIL,INT(MAXROW()/2+2),nT+5) nR:=IF(Col==NIL,INT((MAXCOL()-Lind-6)/2+Lind+8),Col+Lind+8) Scr:=SAVESCREEN(nT,nL,nB+1,nR+1) D_ScrShow(.F.) nB := IF(Txt == NIL, nB , nB-1) IF Sh SHADOW(nT+1,nL+2,nB+1,nR+1) ENDIF @ nT,nL CLEAR TO nB,nR-1 DISPBOX(nT,nL,nB,nR-1,B_SINGLE,Lcolor) D_ScrShow(.T.) nT++ ; nL++ ; nB-- ; nR-- IF TxT == NIL @ nT,nL+Lind/2-13 SAY "Всего " + TRANSFORM(MaxPos,"99999999"); COLOR LColor ELSE @ nT,nL+INT((nR-nL+1-LEN(Txt))/2) SAY Txt ; COLOR LColor ENDIF @ nT+1,nL SAY "0%" Color LColor @ nT+1,nL+2 SAY REPLICATE("-",Lind) Color HColor @ nT+1,nR-4 SAY "100%" Color LColor *@ nT+1,nL+2 SAY REPLICATE(" ",Lind) Color HColor IF Txt == NIL @ nT+2,nL+Lind/2-13 SAY "Обработано " + TRANSFORM(Pos,"99999999") ; COLOR LColor ENDIF IF Txt<>Text Txt:=Text @ nT,nL+1 SAY SPACE(nR-nL-3) COLOR LColor @ nT,nL+INT((nR-nL+1-LEN(Txt))/2) SAY Txt COLOR LColor ENDIF ELSEIF Pos < MaxPos // еще не конец n:=INT(Lind/MaxPos*Pos) Prc:=ROUND(Pos/MaxPos*100,0) IF n != nOld @ nT+1,nL+2+nOld SAY REPLICATE(" ",n-nOld) COLOR ("*"+HColor) ENDIF IF Txt == NIL @ nT+2,nL+Lind/2-2 SAY TRANSFORM(Pos,"99999999") COLOR LColor ENDIF IF Txt<>Text Txt:=Text IF Txt == NIL Txt :="" ENDIF @ nT,nL+1 SAY SPACE(nR-nL-3) COLOR LColor @ nT,nL+INT((nR-nL+1-LEN(Txt))/2) SAY Txt COLOR LColor ENDIF IF prc != nProc IF n > 1 l:=ALLTRIM(STR(Prc)) @ nT+1,nL+2 SAY CENTERS(l+"%",n) COLOR Ucolor ENDIF ENDIF nProc := prc ; nOld := n ELSE // все @ nT+1,nL+2 SAY REPLICATE(" ",Lind) COLOR ("*"+HColor) @ nT+2,nL+Lind/2-2 SAY IF(Txt==NIL,TRANSFORM(Pos,"99999999"),""); COLOR LColor @ nT+1,nL+Lind/2-1 SAY "100%" PICTURE "XXXX" COLOR UColor @ nT+1,nL+2 SAY CENTERS("100%",Lind) COLOR Ucolor n := 0 nOld := 0 Pos := 0 ENDIF RETURN (NIL)

Andrey: PSP пишет: Можно не только прогресс-бар рисовать, а и время затраченное/оставшееся. Чтобы юзеру не скучно было... :) Оставшееся время легко подсчитать. Как подсчитать время на обработку всей БАЗЫ ? Ведь комп иногда подтормаживает в зависимости от нагрузки... Схематично хотя бы алгоритм можно привести ?

Dima: Andrey пишет: Как подсчитать время на обработку всей БАЗЫ ? Вообще я пока такое не реализовывал но на вскидку должно быть так (черновой вариант) Кол-во записей тебе известно , так ?! Подсчитывай сколько уходит времени на обработку 1% записей (процент можно взять и другой) , и вычисляй время для обработки оставшихся записей. Как то так Еще не проснулся , так что вариант PSP более точен , а мой перечеркнем

PSP: Кол-во записей известно. Время старта известно. В любой другой момент времени известно кол-во уже обработанных записей. Зная все это, легко посчитать время, необходимое на оставшиеся записи. Если комп или еще что-то начнет "тормозить", ценочное время тоже начнет расти. Все, собсно... :)

PSP: Dima, я не в коей мере не хотел исправить твой ответ. Просто ответил на вопрос Андрея. :)

Dima: PSP пишет: Dima, я не в коей мере не хотел исправить твой ответ Да все в порядке , говорю же , не проснулся еще когда писал :)

Andrey: Слушайте, не получается... Наверно от погоды такой... У нас жара +36, мозги плавятся, а делать надо... Набросал пример. FUNCTION MAIM() LOCAL nI, cText, nTime1, nTime2, nRecno := 25 SETMODE(25,70) SETCOLOR("11/1") CLEAR SCREEN ? "Тест функций подсчета количества времени обработки дляr [x]Harbour." ? PADC("",69,"-") ? " " + Version() + " - " + hb_compiler() ? ? nTime1 := SECOND() FOR nI := 1 TO nRecno nTime2 := SECONDS() cText := "прошло "+ SECTOTIME(nTime2 - nTime1) + " / осталось " @ 7,10 say LTRIM( Str( nI ) ) + "/" + LTRIM( Str( nRecno ) ) COLOR("15/1") ?? " "+cText INKEY(1.45) NEXT RETURN NIL Подскажите, как высчитать сколько "осталось" времени !

Dima: [pre2] FOR nI := 1 TO nRecno nTime2 := SECONDS() INKEY(1) @ 7,10 say LTRIM( Str( nI ) ) + "/" + LTRIM( Str( nRecno ) ) COLOR("15/1") cText := "прошло "+ SECTOTIME(nTime2 - nTime1) + " / осталось "+SECTOTIME((seconds()-nTime2)*(nRecno-nI)) ?? " "+cText NEXT [/pre2]

Dima: Andrey пишет: У нас жара +36 А у нас +44

Andrey: Спасибо БОЛЬШОЕ Dima !!! А я бегунок вывожу до обработки записи, до INKEY() - из-за этого ничего не получалось....



полная версия страницы