Форум » [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() - из-за этого ничего не получалось....

Andrey: Блин, облом.... FOR nI := 1 TO nRecno nTime2 := SECONDS() INKEY(1.33) // Обработка БАЗЫ // типа если запись обработана, то пропускаем запись @ 7,10 say LTRIM( Str( nI ) ) + "/" + LTRIM( Str( nRecno ) ) COLOR("15/1") cText := "прошло "+ SECTOTIME(nTime2 - nTime1) + " / осталось "+SECTOTIME((seconds()-nTime2)*(nRecno-nI)) ?? " "+cText NEXT Пишет почти всегда что осталось 00:00:00 Как быть ? Dima пишет: А у нас +44 Ваши +44 не сравняются с нашими +36 ! У нас влажность большая, почти 100%... Я жару нормально переношу, в Средней Азии вырос. А здесь, ну просто кранты....

Andrey: Вот примерно сделал так FUNCTION MAIM() LOCAL nI, cText, nTime1, nTime2, nRecno := 15, nTimeOneRec, nKoef :=0 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) cText += " / осталось "+SECTOTIME( nKoef *(nRecno-nI) ) @ 7,10 say LTRIM( Str( nI ) ) + "/" + LTRIM( Str( nRecno ) ) COLOR("15/1") ?? " "+cText INKEY(1.45) nTimeOneRec := SECONDS() - nTime2 nKoef := MAX(nTimeOneRec,nKoef) NEXT RETURN NIL Только при первом запуске пишет, что осталось времени 00:00:00 ....

Dima: Andrey пишет: Только при первом запуске пишет, что осталось времени 00:00:00 .... Значит и выводи соответсвующую месагу при nI равным 1 и пиши что то типа время уточняется (или ориентируйся на nKoef ). Винда ведь при копировании большого кол-ва файлов тоже не сразу показывает сколько времени осталось. В Far Manager аналогично , пару секунд или около того цифры о времени просто не рисуются. ЗЫ А лучше всего вообще ни чего не рисуй пока не обработаешь хотя бы одну запись.

AndreyZh: Форум - гад! Съел такое хорошее моё сообщение... Приведу "кастрированный" вариант: sele base nc := base->(lastrec()) nj := 0 nTimer := seconds() dbgotop() do whil !Eof() ... nPer := ++nJ*100/nC nS := Seconds()-nTimer nT := nS*100/nPer // Прошло @2,21 SAY Ntoc(Int(nT/60),10,2,"0")+":"+Ntoc(nT%60,10,2,"0") // Осталось @2,34 SAY Ntoc(Int(nS/60),10,2,"0")+":"+Ntoc(nS%60,10,2,"0") // Процент выполнения @2,49 SAY Str(nPer,3) DbSkip() endd Вообще можно посмотреть функции (FUNC_NEW.PRG) и их применения в моих исходников: pOpenView Открытие окна_шаблона бегущей строки на фоне экрана дисплея. pChangeView Отражение на шаблоне процента исполнения. Передается процент pCloseView Восстановление окружающей среды программы А в Саратове по термометру 46 - спасаюсь кондиционерами дома и в авто

Andrey: Вот блин поймал прикол ....

Dima: AndreyZh пишет: Съел такое хорошее моё сообщение. Это как ? Может ты замерз под кондиционером и не ту кнопочку нажал (вот форум и не понял) ?

Dima: Andrey пишет: Вот блин поймал прикол

AndreyZh: Это как ? Уже неоднократно! После нажатия "отправить" пишет, что "не удалось". Предлагается вернуться назад и повторить отправку, а набранного сочинения уже нетучки..

Dima: AndreyZh Тогда на всякий пожарный cлучай копируй весь текст перед отправкой в буфер обмена. ЗЫ Какой браузер используешь ? У меня в Opera и Mozilla таких проблем не было , не считая случаев когда глючил форум или мой провайдер.

Andrey: AndreyZh Не работает твой вариант ! Пример здесь FUNCTION MAIN() LOCAL nI, cText, nTime1, nTime2, nRecno := 15, nT, nSec, nPer 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() nPer := nI*100/nRecno nSec := nTime2 - nTime1 nT := nSec*100/nPer cText := "прошло " + Ntoc(Int(nT/60),10,2,"0")+":"+Ntoc(nT%60,10,2,"0") cText += " / осталось " + Ntoc(Int(nSec/60),10,2,"0")+":"+Ntoc(nSec%60,10,2,"0") @ 7,10 say LTRIM( Str( nI ) ) + "/" + LTRIM( Str( nRecno ) ) COLOR("15/1") ?? " "+cText ?? " "+TRANSFORM(nPer,"@ 999%") // Обработка БАЗЫ // Включая, пропуск обработки записей, т.е. на обработку записи тратиться 0 сек. // эмулятор обработки базы INKEY(1.45) // эмулятор обработки базы IF nI == 1 .OR. nI == 5 // пропуск обработки ELSE INKEY(0.21) // эмулятор обработки базы ENDIF NEXT RETURN NIL Кто следующий ?

Dima: Andrey пишет: Кто следующий ? Андрей ты сегодня перегрелся , пора отдохнуть :)

PSP: Значицца так... 1. Прошло времени: nЗатраченноеВремя := nTime2 - nTime1 (nTime2-вычисляется при каждой итерации, nTime1-вычисляется один раз перед началом обработки). 2. Осталось времени (пропорция): nОставшеесяВремя := nЗатраченноеВремя * nВсегоЗаписей / nОбработаноЗаписей.

Andrey: PSP пишет: Значицца так... 1. Прошло времени: nЗатраченноеВремя := nTime2 - nTime1 (nTime2-вычисляется при каждой итерации, nTime1-вычисляется один раз перед началом обработки). 2. Осталось времени (пропорция): nОставшеесяВремя := nЗатраченноеВремя * nВсегоЗаписей / nОбработаноЗаписей. Не пашет ! Может надо nОставшеесяВремя := nЗатраченноеВремя * nВсегоЗаписей / nОбработаноЗаписей - nЗатраченноеВремя ? Dima пишет: Андрей ты сегодня перегрелся , пора отдохнуть :) Это точно.... Башка не варит вообще.... Сейчас у нас дождик прошел... Посвежело...

Andrey: Ура ! Вроде получилось ! Спасибо всем БОЛЬШОЕ ! Рабочий пример здесь .... FUNCTION MAIN() LOCAL nI, cText, nTime1, nTime2, nRecno := 55, nOst, nSec, nPer 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() nPer := nI*100/nRecno nSec := nTime2 - nTime1 nOst := nSec * nRecno / nI - nSec cText := "прошло " + Ntoc(Int(nSec/60),,2,"0")+":"+Ntoc(nSec%60,,2,"0") cText += " / осталось " + Ntoc(Int(nOst/60),,2,"0")+":"+Ntoc(nOst%60,,2,"0") //cText := "прошло " + Ntoc(Int(nSec/60),10,2,"0")+":"+Ntoc(nSec%60,10,2,"0") //cText += " / осталось " + Ntoc(Int(nT/60),10,2,"0")+":"+Ntoc(nT%60,10,2,"0") @ 7,5 say LTRIM( Str( nI ) ) + "/" + LTRIM( Str( nRecno ) ) COLOR("15/1") ? " "+cText ?? " "+TRANSFORM(nPer,"@ 999%") // Обработка БАЗЫ // Включая, пропуск обработки записей, т.е. на обработку записи тратиться 0 сек. // эмулятор обработки базы INKEY(0.42) // эмулятор обработки базы IF nI == 1 .OR. nI == 5 // пропуск обработки ELSE INKEY(0.21) // эмулятор обработки базы ENDIF NEXT RETURN NIL

Dima: Andrey пишет: Это точно.... Башка не варит вообще.... Cлухай ты же не компьютер и башка у тебя не железная , просто отдохни и с утряка все пойдет само собой ;)

Andrey: Dima пишет: просто отдохни и с утряка все пойдет само собой ;) До утра дожить надо.... А утром другие дела нужно делать... Не смотря на воскресенье....

PSP: Andrey пишет: Может надо nОставшеесяВремя := nЗатраченноеВремя * nВсегоЗаписей / nОбработаноЗаписей - nЗатраченноеВремя ? Ну типа того... :) Я просто слеххка был нетрезв... :)

Andrey: Теперь другая напасть. Подсчет остатка идет нормально. Но как случается 00:00 (полночь) то бегунок "глючит" !!! Что делать ?

Dima: Andrey пишет: Но как случается 00:00 (полночь) А подумать ?

Andrey: Dima пишет: А подумать ? Думалка за 2 недели совсем не соображает.....

PSP: nTime1 у тебя к примеру 23:50:00, т.е. 85800 секунд, а nTime2 в полночь становится 0 секунд. 0 - 85800 = -85800, т.е. отрицательное число.



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