Jump to content
php.lv forumi

AnotherUser

Reģistrētie lietotāji
  • Posts

    16
  • Joined

  • Last visited

Posts posted by AnotherUser

  1. 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.

     

    ++

     

    Respektīvi, no MySQL (datu glabātuves) ik pa laikam atlasīt datus un jau sakārtotā veidā pieglabāt kāda NoSQL db, no kuras tālāk atrādīt lietotājam?

  2. 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

  3. 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?

  4. 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

  5. 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.

  6. 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šā..

  7. Var!

    SELECT COUNT(DISTINCT `uId`) as uniq
    FROM `table` as ts 
    WHERE ts.`uId` NOT IN (SELECT ts2.`uId` FROM `table` as ts2 WHERE ts2.`date_hour` != ts.`date_hour`) AND DATE(ts.`date_hour`) = '2013-12-15'
    

    Respektīvi kad man tabulā būs 1M ierakstu, iekš NOT IN (būs 1M id'u..), Neder..

     

    Nu kur ir mūsu LV, DB Gurū..?

  8. Unikalais - unikāls `uId` pa visu tabulu(visām dienam), respektīvi ja tabulā eksistē ieraksts ar `uId` - 101, tad tas ir viens unikals ieraksts un citās dienās/mēnešos/gados, mēs viņu vairs neuzskatam par unikalu.

     

     

    Nezinu, varbūt es kaut ko nesaprotu, bet vai šādi nestrādātu:

    SELECT COUNT(DISTINCT `uId`)
    FROM `table`
    WHERE DATE(`date_hour`) = :date
    ?

     

     

    Šādi tu dabūsi unikalos tikai tā datuma ietvaros, bet tāds `uId` varbūt jau ir bijis vakar vai gadu atpakaļ ierakstījies..

  9. 1. Ja tu domāji ar substr izvilkt 'gads-mēnesis-diena', tad jāsāk no 1. pozīcijas.

    2. Prikškam izmantot substr + date() ? Dubults neplīst?

    3. Dotajs piemērs atlasīs vairākus ierakstus (tik cik unikālie datumi), jo tiek grupēts pēc datuma un noteikti ne-unikālos `uId`

    4. Mēģināšu vēlreiz izskaidrot:

     

    Tātad nepieciešams saskaitīt unikālos `uId` - tā lai rezultātā man atgriež vienu ierakstu (par konkrēto datumu, kuru es pieprasu) ar skaitu cik unikalie, tajā datumā iekrita.

    Unikalais - unikāls `uId` pa visu tabulu(visām dienam), respektīvi ja tabulā eksistē ieraksts ar `uId` - 101, tad tas ir viens unikals ieraksts un citās dienās/mēnešos/gados, mēs viņu vairs neuzskatam par unikalu.

     

    Mans piemērs darbojas no loģiskā viedokļa perfekti, bet neapmierina pats tehniskais izpildījums/ātrdarbība, šķiet jābūt kādam elegantākam risinājumam.

  10. Sveiki, meklēju effektivāku/ātrāku risinājumu..

    Tabulas lauki:
     

    +----+-----+------+---------------+
    | ID | uId | hits | date_hour     |
    +----+-----+------+---------------+
    |  1 | 101 |    2 | 2013-12-01 13 |
    |  2 | 101 |    5 | 2013-12-01 14 |
    |  3 | 101 |    1 | 2013-12-01 15 |
    |  4 | 102 |    3 | 2013-12-01 15 |
    |  5 | 102 |    1 | 2013-12-02 16 |
    |  6 | 103 |    9 | 2013-12-02 17 |
    |  7 | 104 |    4 | 2013-12-02 17 |
    |  8 | 105 |    2 | 2013-12-03 02 |
    |  9 | 106 |    1 | 2013-12-03 10 |
    | 10 | 107 |    1 | 2013-12-03 12 |
    +----+-----+------+---------------+

    Nepieciešams saskaitīt cik unikālie (pa visu laiku) `uId` ir konkrētā dienā, respektīvi no šiem datiem rezultāts būtu sekojoš:
     

    2013-12-01  2(unikālie)
    2013-12-02  2(unikālie)
    2013-12-03  3(unikālie)

    Dotajā brīdī atlasu šādi:
     

    SELECT COUNT(DISTINCT `uId`) as uniq
    FROM `table` as ts
    WHERE (SELECT DATE(ts2.`date_hour`)
            FROM `table` as ts2
            WHERE ts.uId = ts2.uId
            ORDER BY ts2.`id`
            LIMIT 1) = :date
    AND DATE(ts.`date_hour`) = :date

    Paldies.

×
×
  • Create New...