Adott a következő probléma.
Van egy osztály
class A {
String a;
String b;
String c;
float d;
float e;
}
Ebből lenne példányosítva úgy 80-100 ezer példány, amit egy collectionben kellene összefogni, és ebben keresni (nagyon gyorsan!!!), mind az a, b, c mezőkre.
Az "a" mezőre úgy mint pl. az IntelliJ-ben mikor egy osztályra keresek (Ctrl +N)
pl. ha kereső kifejezés az "alm"
akkor megtalálja az
ALMa
AngoL Marha
ÁLMos
ÁLdozatos Munka
Állami Láblógató Minisztérium
stringeket. (Van erre keresésre valami szép magyar vagy angol szakkifejezés?) Az a sebesség amit az IntelliJ tud a keresésre jó lenne. :)
A "b", "c" mezőkre elég lenne sima sql like mintájú keresés, és nem muszáj egy lépésben keresni, ha kell becsomagolom én egy osztályba ami külön külön meghívja az egyes mezőkre a keresést. Vagy az sem gond ha a három kereső mező miatt 3 külön collection lenne.
Van erre valami megoldás?
- 281 megtekintés
Hozzászólások
Szia,
ahogy látom, ez lényegében egy rekord, azaz amit te szeretnél, az valójában egy adatbáziskezelési funkcionalitás.
Ha viszont ilyesmit szeretnél, akkor miért nem töltöd be akár egy in memory SQL adatbáziskezelőbe akár egy lucene-be (http://www.lucenetutorial.com/lucene-in-5-minutes.html)
és oldod meg azon keresztül. A lucene egyébként ennél még jóval többet is tudni fog.
- A hozzászóláshoz be kell jelentkezni
Ez 3 collection lenne amelyben valamilyen indexelheto adat van és mutat a rekord azonosítójára. A like %-kal az elején kevésbé indexelheto (lásd postgres gin index). A betutartalmazas (sorrend nélkül) egy vitterkep index a lehetséges betűkre.
Talan egy postgre/oracle adatbázisba beszurhato vagy saját (in memory) indexelest is csinalhatsz. Csak annyi rám kell bele mint a teljes adaztattalom 2x. Kész is.
Milyen gyakran frissül? Ez is egy szempont...
Az hogy java az mindegy is, ez így egy json is lehet.
- A hozzászóláshoz be kell jelentkezni
A frissülés gyakorisága változó. Lehet egy nap akár ezerszer is, lehet egy hétig egyáltalán nem. De inkább az a jellemző hogy ritkán frissül.
Jelenleg minden egyes keresés az adatbázisból szedi össze az adatokat. Egy select az "a" és "c" mezőre X táblából, majd a következő select a "b" mezőre Y táblából, ezeket mappalem fel az "A" osztályba és a már szűrt adatokhoz szedem fel a "d" és "e" mezőkbe a Z táblából a megfelelő adatokat. Elég nyakatekert az üzleti logika. De mivel általában hosszú időn keresztül nem változnak az adatok és viszonylag kevés van belőlük (szerintem 150 ezernél soha nem lesz több) érdemes lenne a 3 adatbázis táblából a fent említett módon összeszedni az adatokat, és "egy példányban" tárolni, és mivel keresés akár több száz is lehet rá másodpercenként így talán hatékonyabb lenne mint minden kereséskor az adatbázishoz nyúlni.
- A hozzászóláshoz be kell jelentkezni
Komolyan gondoltam a stream api-t, vagy a sima for ciklust, és gyorsan ki is próbáltam: 40 ms alatt megy végig 150 000 tételen, kisbetűsiti (amit előre megtehetsz) az a, b, c-t, és keres benne, egy listába összeszedi az eredményt.
Tehát a desktop gépemen, ami egy 10 ével ezelőtti első sandy bridge i7-es, 40 ms ideig tart egy keresés (egy szálon). Ez lefuthat másodpercenként több százszor is. (a memóriából)
- A hozzászóláshoz be kell jelentkezni
Ez másodpercenként egy szálon pont 25x futhat le.
zászló, zászló, szív
- A hozzászóláshoz be kell jelentkezni
Akkor muszaj lesz tobbszalusitani, esetleg - bizva abban, hogy hasonlo keresesek lesznek - cache-elni az eredmenyt.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
A cache-éles már kész is ha a memóriában van minden. 40ms tökéletes, ennél több nem kell. Szvsz.
- A hozzászóláshoz be kell jelentkezni
Ha összesen 100 000 db példányod lesz, és bent lesz a memóriában, akkor javaslom az egyszerű for ciklust (vagy a stream api-t) mindenféle variálás és kavarás nélkül.
Szerintem gyors lesz.
Egyébként egy érdekesség: Branch Prediction in Java | Baeldung (bár nem hiszem, hogy ezzel most bármi kérdés lenne, csak érdekességként osztom meg)
- A hozzászóláshoz be kell jelentkezni
Pont ezt akartam írni én is.
A posztolónak: a kérdés az, hogy pontosan mi is az, hogy gyorsnak kell lennie? Mérés, vagy elméleti megfontolás van már, hogy mennyit tud a nyers erő, és mennyi kellene?
Vannak mindenféle indexelési módszerek is, például be lehet tenni minden kulcsot 1-1 TreeMap-be kulcsnak (csak körültekintést és szinkron blokkokat (hoppá, skálázódás!) igényel, hogy egyszerre menjen be és ki az adat), azon lehet tartományra keresni, de a hasonló betűket előre le kell butítani, pl: a->A A->A á->A Á->A, stb transzformációval.
- A hozzászóláshoz be kell jelentkezni
Lucene index?
- A hozzászóláshoz be kell jelentkezni