SkyD Posted October 7, 2009 Report Share Posted October 7, 2009 Labs vakars! Ir pienācis laiks, kad ir nepieciešamība izmantot memkeshu, jo daudz datu vnk nevajadzīgi katru reizi tiek izsaukti no datubāzes. Jautājums, vispār, kādus datus vislabāk glabāt memkeshaa? Droši vien tā varētu būt lietotāja profila info, ko viņš redz katru reizi ieejot savā profilā, pareizi? Jo tur principā info mainās pa retam. Bet ja paņem, piemēram, lietotājus onlainā.. Principā tur ir diezgan liels kvēriju pieprasījums.. Kā šo optimizēt? Ir jēga paņemt visus šos online lietotājus iemest memkeshaa, un vilkt ārā visu laiku no memkesha viņus, līdz ko nav parādījies kāads jauns lietotājs klāt? Cik esmu pētijis, tad šo var vienīgi pārbaudīt ar laiku, kad pēdējais lietotājs ir ienācis online, kā arī, kad pēdējo reizi ir memkeša fails atjaunots, pareiz? Zinu veel to, ka stulbi daru, kad vaacu no online lietotaaju tabulas visus lietotaajus un tikai ciklaa pieprasu lietotaaja info vadoties peec lietotaaja ID no online lietotaaju tabulas. Apmeeram shaadi: $query = query("select * from online"); foreach($query as $q) { $user = query("select * from users where id = '$q[user_id]'"); } Kā šo visu padarīt vienkāršāku? Paldies! Quote Link to comment Share on other sites More sharing options...
Trac3 !! Posted October 8, 2009 Report Share Posted October 8, 2009 vienu kvēriju otrā ieliec vai izmanto JOIN vai citu variantu Quote Link to comment Share on other sites More sharing options...
Klez Posted October 8, 2009 Report Share Posted October 8, 2009 (edited) tur var iztikt ar vienu kveriju. kad juzeris ielogojas, update users set pedejo_reizi_redzets = now() where user_id = 'xx'; un online skripts būs: select * from users where pedejo_reizi_redzets > `now() - 30 minūtes` domāju ka domu saprati ko tu gribēji ar memcache darīt ? Edited October 8, 2009 by Klez Quote Link to comment Share on other sites More sharing options...
Kaklz Posted October 8, 2009 Report Share Posted October 8, 2009 lai izvairītos no query ciklā var darīt aptuveni šādi: $query = query("select * from online"); $userids = array(); foreach($query as $q) { $userids[] = $q['user_id']; } $qry = query("select * from users where id IN (" . implode(",", $userids) . ")"); Kas būs stipri labāk par query ciklā. Ja tālāk skaties uz memcache, tad tīri teorētiski tev priekš lietotāja datu ieguves ir jāveido funkcija, kas pa priekšu meklēs lietotāja datus memcache, ja tur tos neatradīs, tad pielasīs no datubāzes. Ja pieņemam, ka memcache lietotāja profila info atslēga ir pats lietotāja identifikators, tad konkrētais augstāk esošais piemērs varētu izskatīties šādi: function getUserData($userids){ // es pieņemu ka tu lieto MC OOP interfeisu un iepriekš globālā namespace ir jau izveidots $mc objekts kas ir savienojies ar serveri. global $mc; // mēģinam no memcache $udata = $mc -> get($userids); if (sizeof($udata) != sizeof($userids)){ // kaut kādi dati memcache nav atradushies - paņemam tos lietotāju id, kas nav atrasti memcache $uidsToGetFromDB = array_diff($userids, array_keys($udata)); // savācam no DB $usersFromDB = query("select * from users where id IN (" . implode(",", $userids) . ")"); foreach ($usersFromDB as $user){ $udata[$user['id']] = $user; // ieliekam uz stundu memcache lai nākamo reizi varētu ņemt no turienes $mc -> set($user['id'], $user, 0, 3600); } } return $udata; } $query = query("select * from online"); $userids = array(); foreach($query as $q) { $userids[] = $q['user_id']; } $onlineUsers = getUserData($userids); Quote Link to comment Share on other sites More sharing options...
Grey_Wolf Posted October 8, 2009 Report Share Posted October 8, 2009 Bet ja paņem, piemēram, lietotājus onlainā.. Principā tur ir diezgan liels kvēriju pieprasījums.. Kā šo optimizēt? Neizmanto statisku tabulu bet gan MEMORY , jo nav nekaads vjadziibas saglabat datus uz HDD. Ja serveris restarteesies, tad tapat neviena Usera nebuus onlinee - visi tiks izsviesti. tikai jatceras ka jauzliek MAX atljautais ierakstu skaits (rows), savadak var sanakt situacija ka Tabula savaks visu pieejamo RAM .. un parejis saks bremzeet . Shis ir glvenais Optimizacijas vrjants, jo rakstisana/lasisana no HDD ir ieverojami lenaka nekaa no RAM. Nemaceshu preciizi pteikt bet varetu buut ~~100X --> HDD piejejas laiks pret RAM piekljuves laiku (Mili sec pret Nano sec) -- Quote Link to comment Share on other sites More sharing options...
SkyD Posted October 8, 2009 Author Report Share Posted October 8, 2009 (edited) Kaklz, paldies! Par MC OOP interfeisu. Dati tiek glabaati uz HDD? Grey_wolf shim noluukam jaizmanto PHP APC? Vai arii jaaveido memchache serveris, pie kura sleedzamies klaat un daram vajadziigaas lietas? Orienteejos peec shii piemeera: http://af-design.com/blog/2009/01/28/php-memory-caching-performance/ Edit: Laikam Kaklz variants par memcache arii atbilst shim piemeeram. Edited October 8, 2009 by SkyD Quote Link to comment Share on other sites More sharing options...
marcis Posted October 8, 2009 Report Share Posted October 8, 2009 Memcached glabājas ramā. Quote Link to comment Share on other sites More sharing options...
krikulis Posted October 8, 2009 Report Share Posted October 8, 2009 (edited) No sākuma iemācies kā SQL kverijus rakstīt / optimizēt, tad pie memkeša ķeries. SELECT u.username FROM online o INNER JOIN users u ON u.id = o.user_id to savukārt pārtaisot uz <?php if(!$online = memcache_get("online")){ $online = $pdo->query("SELECT u.username FROM online o INNER JOIN users u ON u.id = o.user_id")->fetchAll(); memcache_set("online", $online, 600); } Edited October 8, 2009 by krikulis Quote Link to comment Share on other sites More sharing options...
SkyD Posted October 8, 2009 Author Report Share Posted October 8, 2009 Paldies, diezgan labi izprotami piemēri ;) Pagaidām vēl neatradu, vai ir iespējams šādi izlasīt datus pēc to skaita. Piemēram. USER_ID | msg_id ----------------- 2 | 2 3 | 6 2 | 8 5 | 1 3 | 9 2 | 10 Respektīvi, lai visi dati, piemēram, masīvā uzreiz ielasās jau sakārtoti pēc lielākā skaita. Masīvam būtu jaizskatas šādi: $m[0] = 3; // 3 ieraksti db, userim Nr. 2 $m[1] = 2; // 2 ieraksti db, userim Nr. 3 $m[2] = 1; // 1 ieraksts db, userim Nr. 5 Līdz šim izmantoju masīva laišanu caur ciklu, kas sakārto pa vietām, taču tas nav īpaši ātri. Varbūt pie šāda tipa kvērija to var piekabināt? SELECT u.username FROM online o INNER JOIN users u ON u.id = o.user_id Doma man ir šāda: SELECT count(u.user_id) as count FROM ieraksti o INNER JOIN ieraksti u ON u.user_id = o.user_id Quote Link to comment Share on other sites More sharing options...
SkyD Posted October 14, 2009 Author Report Share Posted October 14, 2009 Cerams, ka kāds varēs izpalīdzēt ar sekojošo problēmu. Ar šādu kvēriju: $query = $db->query("SELECT user_id, COUNT(user_id) FROM log_visitors where date='$date' GROUP BY user_id ORDER BY user_id DESC"); saskaitu, cik katram lietotājam ir iekš tabulas log_visitors ierakstu. Problēma ir ar to, ka šeit nestrādā kārtošana dilstošā secībā. Centos pēc tam arī ar sort(); funkcijām kārtot, taču nekā. Ir kāds risinājums? Quote Link to comment Share on other sites More sharing options...
Val Posted October 14, 2009 Report Share Posted October 14, 2009 ? ORDER BY COUNT(user_id) DESC Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.