AnotherUser Posted December 17, 2013 Author Report Share Posted December 17, 2013 (edited) Nū, ja problēma ir ātrdarbība, tad ir jādomā par indeksiem. Bet tīklīdz tu sāc taisīt prikolus ar funkcijām uz kolonnām (DATE()), tā var aizmirst, ka tur kaut kas jēdzīgā laikā izpildīsies, jo jāiet cauri būs pilnīgi visiem ierakstiem. Neesmu baigais specs, bet pamēģini gan to subselektu, gan arī galveno selektu izpētīt ar EXPLAIN un pielāgot tabulu, lai pilnībā tiktu izmantoti indeksi. Minu, ka arī vajadzēs glabāt tikai datumu atsevišķā kolonnā, lai var normāli grupēt. Jā pa lielam problēma ir ātrdarbībā. Dotā tabula ir piemērs un mans sql ir viens no ntajiem subselectiem, tapēc indexi ir salikti optimāli pret visiem sql, kas izpildās šajā tabulā. Ja citi sql izpildās ~125ms tad, šis ~450ms. Pamēģināju variantu bez DATE() funkcijas, pāatrinājās par 50ms, kas arī nav gluži variants.. Uz doto brīdi tabulā ir ~45K ierakstu, kas ir gandrīz nekas salīdzinājumā ar to apjomu, kas tur gāzīsies iekšā.. Edited December 17, 2013 by AnotherUser Quote Link to comment Share on other sites More sharing options...
codez Posted December 17, 2013 Report Share Posted December 17, 2013 (edited) Risinājumi: 1)Glabāt šos datus līdz ar šīs tabulas veidošanu, respektīvi, uztaisīt tabulu, kurā glabā unikālos pa datumiem un tad arī kā nāk jauns ieraksts, skatās vai tāds lietotājs ir un, ja nav, palielina šodienas unikālo skaitu. 2)Ja ir grūti esošā kodā to iekļaut, var izveidot ārēju job-u, kurš ik pa laikam ņem jaunos ierakstus un papildina dienu statistikas lapu. 3)Pielikt kešošanu. Mainīties dati var tikai jaunākām dienām, jo laiks uz atpakaļ neiet. Tad var taisīt kveriju dienām un, ja dati nav kešā, taisa pilno kveriju, savādāk no keša. 4)Ja dati var mainīties arī atpakaļejošos datumos, ņemam skala un akka uztaisām distributētu actor-us, kui ielāde atmiņā visu dataset-u un tad ar map reduce metodēm iegūst rezultātu - šajā gadījumā bez problēmām var izveidot algoritmu, kurš miljoniem ierakstu pilno pārlasi veiks zem 10ms, bet tas atkarīgs no tā cik paralēlas skaitļošanas jaudas būs pieejams. P.S. Iesaku uz db skatīties kā uz parastu data storage un netaisīt tur šadas kompleksas atlases, it sevišķi, ja tās tik un tā prasa apskatīt visus ierakstus. Dzīve būs vieglāka. Edited December 17, 2013 by codez Quote Link to comment Share on other sites More sharing options...
AnotherUser Posted December 17, 2013 Author Report Share Posted December 17, 2013 Starp citu manu sākotnējo sql no subquery pārtaisot par JOIN variantu, izpildās uz 1/2 ātrāk, takā tas pagaidām ir ejošākais variants. Risinājumi:1)Glabāt šos datus līdz ar šīs tabulas veidošanu, respektīvi, uztaisīt tabulu, kurā glabā unikālos pa datumiem un tad arī kā nāk jauns ieraksts, skatās vai tāds lietotājs ir un, ja nav, palielina šodienas unikālo skaitu.2)Ja ir grūti esošā kodā to iekļaut, var izveidot ārēju job-u, kurš ik pa laikam ņem jaunos ierakstus un papildina dienu statistikas lapu.3)Pielikt kešošanu. Mainīties dati var tikai jaunākām dienām, jo laiks uz atpakaļ neiet. Tad var taisīt kveriju dienām un, ja dati nav kešā, taisa pilno kveriju, savādāk no keša.4)Ja dati var mainīties arī atpakaļejošos datumos, ņemam skala un akka uztaisām distributētu actor-us, kui ielāde atmiņā visu dataset-u un tad ar map reduce metodēm iegūst rezultātu - šajā gadījumā bez problēmām var izveidot algoritmu, kurš miljoniem ierakstu pilno pārlasi veiks zem 10ms, bet tas atkarīgs no tā cik paralēlas skaitļošanas jaudas būs pieejams.P.S. Iesaku uz db skatīties kā uz parastu data storage un netaisīt tur šadas kompleksas atlases, it sevišķi, ja tās tik un tā prasa apskatīt visus ierakstus. Dzīve būs vieglāka. 1. Atkrīt jo tad pie ierakstīšanas man būs jātaisa selects, ko es nevaru atļauties mega lielā traffika dēļ. 2. Atkrīt jo statistika nepieciešama in live. 3. Tas atrisinās iepriekšējo dienu statistikas ielādi, bet aktuāli ir šodien un tulīt. 4. Var lūdzu šo nedaudz detalizētāk, scala/akka/distributētu actor-us/... ? Paldies. Quote Link to comment Share on other sites More sharing options...
codez Posted December 17, 2013 Report Share Posted December 17, 2013 (edited) 1. Atkrīt jo tad pie ierakstīšanas man būs jātaisa selects, ko es nevaru atļauties mega lielā traffika dēļ.Reāli jau vienkārši selecti pēc indeksa ir par kārtu ātrāki par insertiem. Bet vajag pamērīt. 3. Tas atrisinās iepriekšējo dienu statistikas ielādi, bet aktuāli ir šodien un tulīt.Var kešā glabāt ari šodienas statistiku, kuru vāc pie apmeklējuma, bet šeit būs tik un tā būs selects un inserts no 1. varianta. 4. Var lūdzu šo nedaudz detalizētāk, scala/akka/distributētu actor-us/... ? http://akka.io/ Ideja ir tāda, ka atlases algoritms strādā kā aktors, viņam padod datus, vai uztaisa, ka dati pieejami un padod intervālu,kuru viņam jāapstrādā. Actori var strādāt paralēli gan uz viena servera (izmantot uzreiz visas kores), gan uz vairākiem. Tātā veidā, piemēram, var n-kāršot darba izpildes ātrumu. Plus pati skala vēl ir krietni ātrāka kā PHP. Piemēram, ja tev ir 10 miljoni ierakstu, kuru pilna pārlase ar mysql aizņemtu kādas 5 sekundes, ar php kādas 100 sekundes, ar skalu kādas 1-2 sekundes. Tad vēl sadalot uzdevumu vairākiem aktoriem, piemēram, (4 servi ar 4 korēm) 16 aktoriem, 1 sekundes darbs tiek izpildīts aptuveni 40ms, kas miljons ierakstu gadījumā būs 4ms. Bet, ja ir šito nav bijusi saskarsme, būs kārtīgs learning curve. Ir vēl citi paralēlu skaitļošanu fw, piem., gridgrain, hadoob, gearman, utml. Edited December 17, 2013 by codez Quote Link to comment Share on other sites More sharing options...
marrtins Posted December 17, 2013 Report Share Posted December 17, 2013 Uz doto brīdi tabulā ir ~45K ierakstuUzmet dumpu kaut kur failiem.lv, lai var paspēlēties. Quote Link to comment Share on other sites More sharing options...
AnotherUser Posted December 17, 2013 Author Report Share Posted December 17, 2013 (edited) Ir vēl citi paralēlu skaitļošanu fw, piem., gridgrain, hadoob, gearman, utml. Paldies, būs ko gremot. Uzmet dumpu kaut kur failiem.lv, lai var paspēlēties. http://failiem.lv/u/agdqhtw?k=57fd6f0c Ar JOIN tomēr nevar to realizēt.. tapēc SQL uz doto brīdi ir SELECT COUNT(DISTINCT `cId`) as uniqs FROM `thread_stats` as ts WHERE ts.tId = 1 AND (SELECT DATE(ts2.`date_hour`) FROM `thread_stats` as ts2 WHERE ts.cId = ts2.cId LIMIT 1 ) = '2013-12-15' AND DATE(ts.`date_hour`) = '2013-12-15' ~450ms Edited December 17, 2013 by AnotherUser Quote Link to comment Share on other sites More sharing options...
marrtins Posted December 17, 2013 Report Share Posted December 17, 2013 Dīvaini tur tie dati. Man sanāk, ka unikāli ir faktiski visi un datums ir tikai viens. Atkārtojas tikai kādi 115 cid un visi divreiz. Izpildās momentā. Quote Link to comment Share on other sites More sharing options...
AnotherUser Posted December 17, 2013 Author Report Share Posted December 17, 2013 (edited) Dīvaini tur tie dati. Man sanāk, ka unikāli ir faktiski visi un datums ir tikai viens. Atkārtojas tikai kādi 115 cid un visi divreiz. Izpildās momentā. Jā, tur ir viena diena un principā vienas stundas intervālā, tapēc arī ir 99% unikālie, bet man arī ar šādiem datiem ir ~400ms. "Momentā" tas ir cik? Tu uz Percona, vai mysql testē? Un kāds dzelzis? Edited December 17, 2013 by AnotherUser Quote Link to comment Share on other sites More sharing options...
daGrevis Posted December 17, 2013 Report Share Posted December 17, 2013 Momentā cilvēkam arī ir 300-400 ms. :D Quote Link to comment Share on other sites More sharing options...
marrtins Posted December 17, 2013 Report Share Posted December 17, 2013 OK, tas momentā ir ~0.759sec ar cold cache :D. Laikam padaudz. Atkārtoti 0.0004 sec. Tava versija ~1.4sec. Dzelzis: 2.2Ghz Opteron 2427 Percona 5.1 SELECT SUM(uniq) FROM ( SELECT COUNT(DISTINCT t1.`cid`) as uniq FROM `thread_stats` t1 WHERE t1.dt = '2013-12-15' AND t1.cid NOT IN (SELECT cid FROM `thread_stats` t2 WHERE dt != '2013-12-15' GROUP BY t2.cid) GROUP BY t1.cid ) as ss; Es atdalīju to date atsevišķā kolonnā un index uz (dt,cid) Quote Link to comment Share on other sites More sharing options...
marrtins Posted December 17, 2013 Report Share Posted December 17, 2013 0.33, izvācot group by no subkverija. SELECT SUM(uniq) FROM ( SELECT SQL_NO_CACHE COUNT(DISTINCT t1.`cid`) as uniq FROM `thread_stats` t1 WHERE t1.dt = '2013-12-15' AND t1.cid NOT IN (SELECT DISTINCT cid FROM `thread_stats` t2 WHERE dt != '2013-12-15') GROUP BY t1.cid ) as ss; Quote Link to comment Share on other sites More sharing options...
marrtins Posted December 17, 2013 Report Share Posted December 17, 2013 Palaidu to pašu uz Percona 5.5 un Opteron 2.8Ghz 8439: 0.19sec Quote Link to comment Share on other sites More sharing options...
AnotherUser Posted December 17, 2013 Author Report Share Posted December 17, 2013 (edited) 0.33, izvācot group by no subkverija. SELECT SUM(uniq) FROM ( SELECT SQL_NO_CACHE COUNT(DISTINCT t1.`cid`) as uniq FROM `thread_stats` t1 WHERE t1.dt = '2013-12-15' AND t1.cid NOT IN (SELECT DISTINCT cid FROM `thread_stats` t2 WHERE dt != '2013-12-15') GROUP BY t1.cid ) as ss; Thanx ;) Mhhm.., bet ir tomēr gļuks, pamēģini ieliec vēl vienu ierakstu ar 14 datumu, kura cId būs arī 15. datumā, velkam ārā par 15. datumu viss pareizi -1 no iepriekšējā rezultāta, bet paskatoties 14. datumu jābūt 1 unikālajam, a mums 0 :/ WHERE dt != '2013-12-15' Ir problēma Edited December 17, 2013 by AnotherUser Quote Link to comment Share on other sites More sharing options...
spainis Posted December 17, 2013 Report Share Posted December 17, 2013 (edited) http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html Starp citu manu sākotnējo sql no subquery pārtaisot par JOIN variantu, izpildās uz 1/2 ātrāk, takā tas pagaidām ir ejošākais variants. 1. Atkrīt jo tad pie ierakstīšanas man būs jātaisa selects, ko es nevaru atļauties mega lielā traffika dēļ. Paldies. http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html pa kruto protams būtu kāds streaming map reduce's Edited December 17, 2013 by spainis Quote Link to comment Share on other sites More sharing options...
Kavacky Posted December 17, 2013 Report Share Posted December 17, 2013 P.S. Iesaku uz db skatīties kā uz parastu data storage un netaisīt tur šadas kompleksas atlases, it sevišķi, ja tās tik un tā prasa apskatīt visus ierakstus. Dzīve būs vieglāka. ++ 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.