ugrás a tartalomhoz

Adatbázis kérés eredményének előtöltése

world-s · 2013. Jún. 5. (Sze), 19.51
Sziasztok!

Gondolkoztam azon, hogy hogyan lehetne egy nagyobb terhelésű oldalnál a bonyolultabb kereséseket (pl. ügyfelek különböző paraméterek alapján történő keresése) gyorsítani.

Arra gondoltam, hogy lehetne esetleg azt csinálni, hogy ha az ügyfél elindít egy keresést, akkor ha nekem az első 10 rekordra van szükségem, akkor mi lenne ha nem 10 hanem mondjuk 20-30 rekordot kérdeznék le.
Az eredmény többletet (a +10-20 rekord)pedig fognám és eltárolnám mondjuk memcache-be, session-ba, stb.
Amikor az oldalt görgeti tovább az ügyfél, és szüksége lenen a következő 10 rekordra, akkor ebben az esetben megnézném, hogy ismerem -e már a kért adatot, vagy sem.
Ha nem, akkor természetesen ugyanazt csinálnám mint az előbb.
Ha viszont ismerem, akkor minden féle (my)SQL művelet nélkül, mindenféle bonyolult SQL QUERY futtatása nélkül oda tudom adni az ügyfélnek. Miután ezt megteszem, akkor pedig valami háttér folyamatnak átadnám azt, hogy amikor van szabad kapacitás, akkor töltsön előre nekem további újabb rekordokat, hogy amikor vélhetőleg pár másodperc múlva jön az ügyfél a kéréssel, akkor már az is elő legyen költve.
Ugye fontos, hogy egy külön folyamat végezze az előtöltést, mert különben be kellene várni az előtöltés eredményét a kiszolgálás előtt.

Az érdekelne, hogy szerintetek ilyen módszerrel lehet valós teljesítménynövekedést elérni?
A másik kérdés, hogy ha ez egy járható út, akkor szerintem biztos nem én vagyok az első aki ezzel foglalkozott. Lehet hogy erre már vannak kész megoldások is. Én kerestem, de nem igazán találkoztam. Tehát a másik kérdés, hogy ilyennel már találkozott -e valaki? Ha igen, akkor hol?

Segítségeteket előre is köszönöm.
Zoli
 
1

Ennyi erővel ki is küldhetnéd

Hidvégi Gábor · 2013. Jún. 5. (Sze), 20.06
Ennyi erővel ki is küldhetnéd a 10 helyett mindjárt a 30 adatot, csak mondjuk nem kéne mindet megjeleníteni.

Másrészt érdemes előbb feltérképezni, hogyan használják a keresőt, az is lehet, hogy a legtöbb esetben az első tízben megtalálják a szívük vágyát, és akkor nem kell csinálni semmit.
2

Szia! Köszi a

world-s · 2013. Jún. 5. (Sze), 21.55
Szia!
Köszi a választ.

Valóban ez egy előre gondolkodás csak, mert tényleg majd a használat nagyon sok mindent eldőlt.
Csak ha véletlen valaki hallott már ilyenről, vagy hasonló kész megoldásról, akkor inkább azt tanulmányozza az ember, mint nulláról próbálja végigjátszani.

Ez a kis szám amúgy csak a példa kedvéért volt. Természetesen sokkal nagyobb számokról lenne szó, és nem is feltétlen a teljes adatsor lenne betárazva, hanem csak mondjuk az ID-k. Azt gondoltam, hogy ha 10 helyett egyszerre 30-40 rekordot kérek egy összetett SQL-ből, és azt nem is feltétlen minden mozzanattál tölteném elő (lehet minden 2. 3. alkalommal töltenék csak elő adatot), akkor az jóval kevesebb erőforrásba és jóval gyorsabb működést eredményez, ha az oldal működése modellje miatt az ügyfelek folyamatosan kattogtatni fognak mint az állat.

Abból indultam ki, hogy a szűrés az lehet hogy egy kritikus pont (mert az oldal működése modellje miatt az ügyfelek folyamatosan kattogtatni fognak mint az állat), ahol különböző tulajdonságok szerinti szűrés egy lassabb működést okozhat.

Azt gondoltam, hogy ha 10 helyett egyszerre 30-50 rekordot kérek egy összetett, bonyolult SQL-ből, valamint az a tény, hogy nem is biztos, hogy minden szerver kéréskor rögtön fontos a tárat utántölteni (lehet minden 2. 3. alkalommal töltenék csak elő adatot), akkor az jóval kevesebb erőforrásba kerül és jóval gyorsabb működést eredményezhet.

Természetesen ha a keresett ügyfelek, vagy termékek (stb.) előre lennének tárazva (csak az ID lenne előtárazva), akkor ilyenkor már csak a jól indexelt ID alapján kell kikeresni, és kiírni az adatokat az ügyfél képernyőjére.

Mondhatnám ez lenne az elméletem, ami persze lehet hibás, de az is lehet, hogy létezik már kész megoldás is ilyenre, vagy hasonlóra.

Kicsit olyan mint CPU, HDD, stb. esetén amikor megpróbálja az adott rendszer megjósolni, hogy mi lesz a következő szükséges adat, és azt előkészítni/előtölti.
3

Gyorsítótár

Poetro · 2013. Jún. 5. (Sze), 22.13
Szinte minden adatbázismotorban van gyorsítótár, ami vagy a lekérdezéseket, vagy azok eredményeit tárolja. Jó eséllyel ezek beállítása megoldja a sebességproblémákat. Ezen kívül komplett eredményeket is lementhetsz vagy adatbázisba vagy fájlrendszerbe, és akkor nem kell őket újra futtatni, csak kiolvasni. Természetesen bármilyen gyorsítótár használata esetén a legsarkalatosabb pont magának a gyorsítótárnak a törlése. Azaz tudni kell mikor kell törölni, és mit. Ugyanis létrehozni nem túl nagy ördöngősség.
4

Poetro! Nem jártam utána

world-s · 2013. Jún. 5. (Sze), 23.29
Poetro!
Nem jártam utána annyira a dolognak. Tudom, hogy van a pl. a mySQL-nek is gyorsítótára, csak azt nem tudom, hogy ott a már lekérdezett adatokat lehet újra visszaolvasni gyorsabban, vagy valóban akár előre is olvas, hátha kell még rekord az elsőre lekért 10-en túl is.

Bár ha nem olvas előre, akkor is lehet ki lehet kényszeríteni, ha jegyzem, meddig kértem le, és időnként többet kérdezek annak érdekében, hogy azt előtárazza a mySQL.

Amúgy a meglátásod jogos. Nagyon könnyű gyorsítótárazni, de egy jó gyorsítótárnak tudnia kell azt is mikor érdemes az adatokat dobni. Ezért érdekelne, hogy hátha valaki látott már valamilyen kész megoldást.
8

Ha olyan bonyolult a

MadBence · 2013. Jún. 6. (Cs), 19.21
Ha olyan bonyolult a lekérdezés, akkor valószínűleg nem csak az első 10 eredményt állítja elő a mysql, hanem az összeset (tehát a probléma meg van oldva). Gondolj bele, van pl egymillió rekordod, és abból a valamilyen szempont szerint a 100 legnagyobbat szeretnéd kiválasztani. Ilyenkor az egész eredményhalmaz rendezését el kell végezni.

Jó indexek elhelyezésével szerintem többet lehet nyerni teljesítményben. Ha az előző példánál maradunk: ha a feltétel elsődleges kulcsra vonatkozik, akkor pl rendezni sem kell(!), hiszen fizikailag rendezett. Ha másodlagos indexet használsz, akkor is csak az indexeket kell beolvasni, magukat a rekordokat nem (ez is sokat tud dobni rajta).
6

Előre optimalizálás

Hidvégi Gábor · 2013. Jún. 6. (Cs), 18.57
Ahogy webproghu írja az 5-ösben, csak akkor kell a problémával foglalkozni, ha felmerül. Egyrészt addig fölöslegesen pazarlod az idődet, másrészt egy jóval bonyolultabb kódot eredményezhet, ami esetleg több gondot okoz, mint amennyit megold. Sosem szabad előre optimalizálni.

Ahogy Poetro írja a 3-asban, először érdemes az adatbázis gyorstárait belőni. Az innodb pool nem dedikált szerver esetén a teljes memória 50%-a lehet, továbbá lehet játszani a query cache-sel, bár ez csak akkor hatékony, ha viszonylag kevés lekérdezést használnak véges időn belül.
Ha sok adattal dolgoztok, a rendezéshez használt puffermérettel is lehet próbálkozni, bár ezzel eléggé el lehet szállni (ha gyakoriak a lekérdezések, sok memóriát eszik).

Emellett azt is meg kell nézni az EXPLAIN segítségével, hogy a táblák rendesen be vannak-e indexelve.

Ha izzad a vas, a mai árak mellett előbb érdemes annyi memóriát tömni a szerverbe, amennyit csak elbír, aztán szabad csak bármilyen fejlesztést elkezdeni.
5

Létezik ez a nagy terheltségű

webproghu · 2013. Jún. 6. (Cs), 18.26
Létezik ez a nagy terheltségű oldal, illetve valóban akkora a terhelés, hogy szükség van erre? Ha nem, akkor felesleges ezzel foglalkoznod, ráérsz akkor ha már valóban problémát jelent a dolog.

Viszont ha mégis valós a gond, akkor írhatsz egy daemon-t mondjuk PHP-ban, ami bizonyos paraméterek alapján feltölti a cache-t. Ha a felhasználód elkezd keresni, eljut az első oldalra, a háttérben küldesz egy parancsot a daemon-nak a keresés fontosabb paramétereivel, hogy töltse be memcache-be a következő oldalak eredményeit.
7

php daemon

Hidvégi Gábor · 2013. Jún. 6. (Cs), 18.58
Sajnos a php nem túlzottan alkalmas daemonnak, mert sok helyen szivárogtatja a memóriát, esetleg inkább fastcgi-ként érdemes elindítani, aztán cronból időnként hívogatni.
9

Köszönöm

world-s · 2013. Jún. 7. (P), 09.37
Köszönöm az eddig építő jellegű hozzászólásokat.

Lehet nem derült teljesen ki, de nem feltétlenül ennek kifejlesztésével szeretném tölteni az időt, mert tényleg nagyon sok nyitott kérdés van, hogy az esetleges előnyök mellett nehogy több hátrány legyen belőle.

Az elgondolás abból jött, hogy összetett keresésnél már most az elején van egy kritikusabb pont (ami nagyságrendekkel lassabban fog futni mint más), és ha van valahol már egy kész kidolgozott eljárás a neten, akkor miért ne készülhetnék fel az adott rész a tehermentesítésére.

Tehát nem feltétlen az a cél, hogy most erre egy külön fejlesztést induljon a nulláról. Nem azzal szeretném az időt tölteni, hogy tesztelve legyen mi a jó megoldás. Külön daemon dolgozzon -e alá, vagy elég ha minden 4., 5. lekérdezéskor 10 helyett 40-50 rekordot kérek le (mert ezzel minimálisan növekedik csak a futásidő), és cserébe a következő 4-5 kéréskor 3km hosszú SQL helyett csak egy egyszerű SQL kell csak használnom amibe memcache-ból beleírom azt a 10 profil ID-t amire kíváncsi vagyok...

A rendszer még a végleges specifikáció lezárása előtt van, és ha létezik elérhető kész megoldás ami nem hátráltatja a fejlesztést, akkor miért ne tenném bele mint megoldandó feladat (legyen az a megoldás beleépítése, vagy az, hogy eleve tudja egy mozdulattal fogadni azt).

Ezért volt az eredeti kérdés inkább az, hogy ismer -e valaki olyan kész projectet a neten, amit szabadon, vagy akár fizetősen fel lehet használni a leírt problémára ha az bekövetkezne.

Azt láttam neten, hogy nem én vagyok az első akinek mindez eszébe jutott.
10

Optimalizálás

Poetro · 2013. Jún. 7. (P), 10.21
Én előbb az adatbázist optimalizálnám, ha kell, akkor esetleg, de csak tényleg ha fontosak azok a lekérdezések, mert gyakoriak, akkor denormalizálnám esetleg az érintett táblákat, vagy egy duplikáltat hoznék létre a kérdéses lekérdezés segítéséhez.