Ronalds Ierakstīts Augusts 27, 2014 Share Ierakstīts Augusts 27, 2014 Varbūt te ir kāds Oracle specs kurš spēs pakomentēt. Pirmā problēma - ir divas tabulas REKINI un REKINI_PRECES. Precēs ~1 miljons ierakstu. Softs automātiski ģenerē rēķinus (vairākus simtus), kļūdas gadījumā viņi jādzēš ārā. Ja dzēšam ārā ar SQL (delete from REKINI where id in (1,2,3,4,5,6,7..... utt utjp)) dzēšas ārā nesamērīgi ilgi - gaidīju kādu stundu, nesagaidīju.... ID sarakstu ģenerē klienta GUI . Problēma ir nenormāli lēnā dzēšanā no tabulas REKINI_PRECES, kas notiek pēc foreign key delete cascade. Pārtaisīju gui lai dzēš ārā pa vienam ierakstam. Tad dzēšana notika "ņiprāk" - apmēram 1 -2 rēķini sekundē un pēc ~10min 700 uzģenerētie rēķini tika izdzēsti. Padomi ko google ātrumā izmeta - atslēgt indeksus, izmantot ierakstu kopēšanu uz pagaidu tabulām ar pēcāku pārsaukšanu neder - dzēšanai jānotiek no gui uz strādājošas DB. On delete trigeru nav. Tiešām ORACLE nemāk normāli dzēst ierakstus? Otrā problēma - Rēķinu rindām vajag lauku "numurs pēc kārtas" -NPK lai varētu useris no gui kārtot preces rēķinā kā viņiem iepatīkas. Vajag šo lauku aizpildīt ieteicams ar trigeri ar soli 10. Trigerī on insert or update rakstām: if :new.NPK is null then select max(npk)+10 into :new.npk from REKINI_PRECES where rekins_id=:new.rekins_id; end if; if :new.NPK is null then :new.npk := 10; end if; Skuju ziepes - mutating trigger table error. Izrādās ORACLE neļauj no trigera veikt nekādus pieprasījums tabulai no kuras šis trigers ir izsaukts... Labi, ir situācijas kad tas var radīt problēmas, tomēr vismaz uz firebird tas strādā.... Workarounds - viltīgas manipulācijas iekš package... Nu labi, uztaisīšu NPK aizpildīšanu no GUI. Bet ierakstu dzēšanas ātrums reāli kretinē....... Link to comment Share on other sites More sharing options...
basic Augusts 27, 2014 Share Augusts 27, 2014 Varbūt vienkāršāk būtu ielikt rēķinu ģenerēšanu transakcijā, nekā čakarēties ar dzēsanu. 1 Link to comment Share on other sites More sharing options...
Ronalds Augusts 27, 2014 Author Share Augusts 27, 2014 Bet ir takš rēķinu generēšana tranzakcijā. Problēma tur ka kļūdas vēlāk pamana. Link to comment Share on other sites More sharing options...
basic Augusts 27, 2014 Share Augusts 27, 2014 Nu, tad vēl vari pamēģināt atteikties no IN operatora, dzēšamo ierakstu ID ievietot pagaidu tabulā un to džoinot pie REKINI tabulas. Link to comment Share on other sites More sharing options...
nevertell Augusts 27, 2014 Share Augusts 27, 2014 Dari kā beisiks saka, uztaisi temp tabulu ar dzēšamajiem ID, džoino un dzēs. Vispār jau transakciju modelis tam arī ir domāts, lai kļūdas izravētu pirms tiek veiktas izmaiņas tavā kaķu bāzē. Link to comment Share on other sites More sharing options...
Ronalds Augusts 27, 2014 Author Share Augusts 27, 2014 ir mēģināts, nelīdz. In nav pie vainas. Delete from rekini where rekini.grupa_id= 1000 Arī nenormāli lēni. Pie vainas ir nenormāli lēnā dzēšana no tabulas rekini_preces. Tabula ir salīdzinoši liela, bet nekas īpašs priekš mūsdienām. Link to comment Share on other sites More sharing options...
nevertell Augusts 27, 2014 Share Augusts 27, 2014 Nu skaties pats, vai tā ir dzēšana, vai konkrētā ieraksta atrašana. Link to comment Share on other sites More sharing options...
Ronalds Augusts 27, 2014 Author Share Augusts 27, 2014 Tātad Select * from rekini_preces where rekins_id in (1,2,3,... utt kopā pāris simti id) - Izpildās praktiski momentāli, visu ierakstu (pāris tūkstoši) fech notiek pāris sekundēs. DELETE from rekini_preces where rekins_id in (1,2,3,... utt kopā pāris simti id) - nevar sagaidīt kamēr izpildīsies, pa 1h nebija pabeidzies. Serverim vienai corei 100% noslodze un viss. Tabulā REKINI_PRECES ap 1 miljons ierakstu, kādi 20 lauki, pāris indeksu. Kā jau teicu nav maza tabula, bet nu ne jau tik traki! Link to comment Share on other sites More sharing options...
Biete Augusts 27, 2014 Share Augusts 27, 2014 (labots) Viens variants ir fiziski nedzēst, bet vienkārši atzīmēt, ka rēķins ir dzēsts un nerādīt to vairs GUI. Bet nu pie 1 miljona ierakstiem nevajadzētu būt šādām problēmam. Tas, ka pie dzēšanas ar IN, ir lēnu varētu liecināt, ka neizmantoja indeksu uz rekini_preces tabulu un tāpēc tā arī nebeidzās. Ar statistikām viss kārtībām? edit: anyway vajag trace palaist un tad skatīties, kas bremzē Labots Augusts 27, 2014 - Biete 1 Link to comment Share on other sites More sharing options...
nevertell Augusts 27, 2014 Share Augusts 27, 2014 Erm, laikam tad beigšu uzbāsties ar nepareizajiem piedāvājumiem. Tikai izsaku līdzjūtību, ka tev jācīnās ar dupšainiem risinājumiem. Link to comment Share on other sites More sharing options...
Ronalds Augusts 27, 2014 Author Share Augusts 27, 2014 (labots) Viens variants ir fiziski nedzēst, bet vienkārši atzīmēt, ka rēķins ir dzēsts un nerādīt to vairs GUI. Lūk, lieta ir tāda ka es šo sistēmu netaisīju no nulles, bet pārņēmu. Iepriekšējais programmētājs tā ari darīja - atzīmēja ierakstu un nerādīja iekš gui. Tāpēc jau ir tik mega daudz rēķinu - firma ir salīdzinoši neliela un vismaz 2/3 no rēķiniem ir dzēšami. Bet nu dēļ tā lielā daudzumu arī daži select pieprasījumi uz tabulu REKINI_PRECES sāk iebremzēt.... Negribās to bezjēgā audzēt. Ar statistikām viss kārtībām? Kā šo pārbaudīt? Kas ir labi, kas nē? Ps. Man ir divi minējumi - pirmais ka Oracle tiešām nemāk normāli dzēst ierakstus, ne velti pilns webs ar padomiem uztaisīt temp tabulu ar tādiem pašiem laukiem, pārkopēt ar merge visu vajadzīgo uz to tabulu, nomest īsto tabulu un pārsaukt temp tabulu par īsto, pievienot indeksus. Jo cik ir bijusi darīšana ne uz mssql, ne firebird, ne mysql ar dzēšanu problēmu nav bijis. Otrs - ka kaut kas servera konfigā nav kārtībā..... Labots Augusts 27, 2014 - ronalds_ Link to comment Share on other sites More sharing options...
Biete Augusts 27, 2014 Share Augusts 27, 2014 Oracle parasti problēmas sākas, ja dzēš miljons rindas no daudzmiljonu tabulām Tad vajag veikt viltīgas mahinācijas (vai nu merge vai truncate+insert), bet šim nevajadzētu būt tādam gadījumam. Vai arī dzelzis ir sūds... Statistikas var nočekot no all_tables tabulas where table_name = 'tabulas_nosaukums'. Tur ir lauks last_analyzed, kas tad norāda, kad pēdējo reizi ir savāktas statistikas. Ja tas ir nesen, tad vajadzētu būt ok, tur galvenais, lai vispār tiek vāktas. Link to comment Share on other sites More sharing options...
Ronalds Augusts 27, 2014 Author Share Augusts 27, 2014 (labots) Tā lauks last_analyzed=2014/06/09/ 22:49:35 Vai nav tā kā drusku pasen? Dzelzis ~5 gadi vecs 2 proču Xeon (kopā 8 cores) 8 gb ram, 7200 rpm sas diski piektajā raidā. Labots Augusts 27, 2014 - ronalds_ Link to comment Share on other sites More sharing options...
Biete Augusts 27, 2014 Share Augusts 27, 2014 Nu tur atkarīgs, cik daudz dati mainījušies pēc tā datuma. Ja tad bija 100 ieraksti un tagad ir 1 miljons, tad statistikas ir vecas. Ja bija 900k un tagad ir 1 miljons, tad +- OK. Anyway var tās savākt ar dbms_stats. gather_table_stats (tur vajag norādīt tikai owner un table_name, pārējos parametrus atstāj defaultos) un tad vēlreiz patestēt. Ja problēma saglabājas, tad var jau arī būt kāds Oracle/OS bugs. Bet es ieteiktu palaist trace (http://docs.oracle.com/cd/B10500_01/server.920/a96533/sqltrace.htm), pēc tam pēc tkprof parsēšanas varēs redzēt, kas tieši bremzē. Ja to veic pirmoreiz, tagad bik jāiebrauc procesā, bet tas nav nekas sarežģīts. Savādāk tagad sanāk tikai zīlēt. Vēl var pamēģināt palaist ko šādu, ja saki, ka atlasīšana strādā ātri: DELETE FROM rekini_preces WHERE rowid IN (SELECT rowid FROM rekini_preces WHERE rekins_id IN (1,2,3, ..) ). 1 Link to comment Share on other sites More sharing options...
Ronalds Augusts 27, 2014 Author Share Augusts 27, 2014 Par to trace - Oracle dokumentācija ir diezgan nesaprotama... Moš ir kāda step by step guide iesācējiem. Serveris ir uz linux, kā klientu izmantoju TOAD freeware (mož ir kas labāks...?) Par to ROWID - būs rīt jāpamēģina, moš nostrādā. Link to comment Share on other sites More sharing options...
Mezavecis Augusts 27, 2014 Share Augusts 27, 2014 Jebkurā citā lielā DB ir šādas problēmas un ierakstu dzēšana ir viena no lēnākām darbībām. Oracle parasti problēmas sākas, ja dzēš miljons rindas no daudzmiljonu tabulām Cik nācies veidot n-tās CRM sistēmas, rēķinu dzēšana tiek aizliegta pilnībā nederīgās pozīcijas atzīmējot ar mārķeriem, jo parasti rēķini ir saistīti ar vēl daudzām tabulām, kas grauj datu integritāti Ļoti vēlams, lai kļūdaina informācija nenonāk datubāzē izmantojot transakcijas, vai sliktākā gadījumā starptabulu, kuru pa laikam ar truncate var nonest pilnībā. Normālai indeksētai tabulai nav problēmas ar ātrdarbību pat ar n miljoniem ierakstiem. 1 Link to comment Share on other sites More sharing options...
Azazel Augusts 28, 2014 Share Augusts 28, 2014 (labots) awr reports? Labots Augusts 28, 2014 - Azazel Link to comment Share on other sites More sharing options...
Helmars Augusts 28, 2014 Share Augusts 28, 2014 Trigger vietā vajadzētu izmantot SEQUENCE. Ātrdarbības problēmu izraisa droši vien neadekvāts izpildes plāns. Vajag pārliecināties, ka eksistē indekss VALID statusā, vajag daudzmaz atbilstošu statistiku tabulai un indeksam. Ja SQL trace un explain atgriež stipri atšķirīgu ierakstu skaitu, tad ir skaidrs, ka izpildes plāns būs nepareizs. Vēl var paskatīties, kādi wait eventi notiek tai sesijai. Varbūt patiesībā ir citi traucēkļi. Link to comment Share on other sites More sharing options...
VIL Augusts 28, 2014 Share Augusts 28, 2014 autor, iepostē dzēšanas komandas izpildes plānu Link to comment Share on other sites More sharing options...
Recommended Posts
Izveido kontu, vai pieraksties esošajā, lai komentētu
Jums ir jābūt šī foruma biedram, lai varētu komentēt tēmas
Izveidot jaunu kontu
Piereģistrējies un izveido jaunu kontu, tas būs viegli!
Reģistrēt jaunu kontuPierakstīties
Jums jau ir konts? Pierakstieties tajā šeit!
Pierakstīties tagad!