Netværk
Først og fremmest siden du brugte rowid og rownum er vendor-lock alligevel, bør du overveje at bruge databaselagrede rutiner. Det kan reducere omkostningerne ved overførsel af data fra databasen til applikationsserveren betydeligt (især hvis de er på forskellige maskiner og forbundet via netværk).
I betragtning af, at du har 80 millioner poster at overføre, kan det være det bedste præstationsboost for dig, selvom det afhænger af, hvilken type arbejde dine tråde udfører.
Øget båndbredde ville naturligvis også hjælpe med at løse netværksproblemer.
Disk ydeevne
Før du foretager ændringer i koden, skal du kontrollere harddiskbelastningen, mens opgaver kører, måske kan den bare ikke håndtere så meget I/O (10 tråde læses samtidigt).
Migrering til SSD/RAID eller klyngedatabase kan løse problemet. Mens du ændrer den måde, du får adgang til databasen, vil det ikke i det tilfælde.
Multithreading kunne løse CPU-problemer, men databaser afhænger for det meste af disksystem.
Rownum
Der er et par problemer, du kan støde på, hvis du vil implementere det ved hjælp af rowid og rownum.
1) rownum genereres på farten for hver forespørgsels resultater. Så hvis forespørgslen ikke har eksplicit sortering, og det er muligt, at nogle poster har et andet rækkenummer, hver gang du kører forespørgslen.
For eksempel kører du det første gang og får resultater som dette:
some_column | rownum
____________|________
A | 1
B | 2
C | 3
så kører du det for anden gang, da du ikke har eksplicit sortering, beslutter dbms (af en eller anden grund kendt af sig selv) at returnere resultater som denne:
some_column | rownum
____________|________
C | 1
A | 2
B | 3
2) punkt 1 antyder også, at hvis du vil filtrere resultater på rownum det vil generere en midlertidig tabel med ALLE resultater og filtrer det derefter
Så rownum er ikke et godt valg til at opdele resultater. Mens rovid virkede bedre, den har også nogle problemer.
Rovid
Hvis du ser på ROWID-beskrivelsen kan du bemærke, at "rovid-værdi entydigt identificerer en række i databasen ".
På grund af det og det faktum, at når du sletter en række, har du et "hul" i rækkefølgen, kan rækker fordeles ikke ligeligt mellem tabelposter.
Så hvis du for eksempel har tre tråde og hver henter 1.000.000 rækker, er det muligt, at én vil få 1.000.000 poster og to andre 1 post hver. Så én vil blive overvældet, mens to andre sulter .
Det er måske ikke en stor sag i dit tilfælde, selvom det meget vel kan være det problem, du står over for i øjeblikket med det primære nøglemønster.
Eller hvis du først henter alle rækker i dispatcher og derefter deler dem ligeligt (som peter.petrov foreslog), det kunne gøre tingene, selvom det at hente 80 millioner id'er stadig lyder af meget, tror jeg, det ville være bedre at lave opdelingen med en sql-forespørgsel, der returnerer grænser for bidder.
Eller du kan løse det problem ved at give et lavt antal rækker pr. opgave og bruge Fork-Join framework introduceret i Java 7, men det bør være brugt omhyggeligt .
Også indlysende pointe:både rownum og rowid er ikke bærbare på tværs af databaser.
Så det er meget bedre at have din egen "sharding"-kolonne, men så skal du selv sørge for, at den opdeler poster i mere eller mindre lige store bidder.
Husk også, at hvis du skal gøre det i flere tråde, er det vigtigt at tjekke, hvad låsetilstandsdatabasen bruger , måske låser det bare bordet for hver adgang, så er multithreading meningsløst.
Som andre foreslog, må du hellere først finde ud af, hvad der er hovedårsagen til lav ydeevne (netværk, disk, databaselåsning, trådsult eller måske har du bare suboptimale forespørgsler - tjek forespørgselsplanerne).