Topic: Preformancas: join vs. multi-query

Jau kelios vietose esu pastebėjęs, kad turint hasMany HABTM ryšius yra naudojamas ne join'as bet kelios atskiros užklausos.
Pirma užklausa paima rezultatus iš pradinės lentelės, kita, jau išanalizavus rezultatus su php, suformuoja kita užklusą kur pvz pradine_id IN (reiliamų id sąrašas).

Iš vienos pusės, viską padaryti viena užklausa lyg ir paprasčiau bei logiškiau, bet giliau pamąsčius darant 2 užklausas išvengiama tų pačių duomenų išėmimo kelis kartus (jei Pertas turi 10 skelbimų, o man reikia ir visų Petro duomenų, tai darant su join Petro profilis bus paimtas 10 kart, su 2 užklausom - tik 1, HABTM atveju "susitaupo dar daugiau).

Tad ar mano žinos buvo kiek pasenusios, ar čia dar kur šuo pakastas? :)

Re: Preformancas: join vs. multi-query

Lukas wrote:

Jau kelios vietose esu pastebėjęs, kad turint hasMany HABTM ryšius yra naudojamas ne join'as bet kelios atskiros užklausos.
Pirma užklausa paima rezultatus iš pradinės lentelės, kita, jau išanalizavus rezultatus su php, suformuoja kita užklusą kur pvz pradine_id IN (reiliamų id sąrašas).

Tai pabandyk patestuoti, manau turėtum gauti daug blogesnį rezultatą. Taip daro tikriausiai nemokšos (-;

Lukas wrote:

Iš vienos pusės, viską padaryti viena užklausa lyg ir paprasčiau bei logiškiau, bet giliau pamąsčius darant 2 užklausas išvengiama tų pačių duomenų išėmimo kelis kartus (jei Pertas turi 10 skelbimų, o man reikia ir visų Petro duomenų, tai darant su join Petro profilis bus paimtas 10 kart, su 2 užklausom - tik 1, HABTM atveju "susitaupo dar daugiau).

čia reikia skirti du atskirus uždavinius: vienas, kai reikia išgauti susijusius duomenis iš vienas-su-daug, o kitas, kai reikia išgauti iš daug-su-daug.

Jeigu yra vienas profilis ir daug susijusių įrašų, tai aš irgi daryčiau dvi užklausas, vieną profiliui, o kitą įrašams.

Re: Preformancas: join vs. multi-query

Tiesą sakant taip berods daro cakePHP freimworkas, o jis lyg ir prie geresnių yra priskiriamas. Reiks šiom dienom prisėsti ir giliau pažiūrėti, jei labai neužtingėsiu :D

Iki šiol giliau neanalizavau, nes kiek reikėdavo, tai localhoste automatiškai sudarytos užklausos netrukdavo ilgiau 9-80ms įskaitant DESCRIBE (debug modas :)) ir keletą bereikalingų, be to nemačiau tikslo viską optimizuoti, juolab kad beveik visada galioja Pareto principas ir tam sugaištas nelabai atsipirktų.

Beje jei neklystu, kažkur buvau matęs kad IN () yra gana lėta funkcija. Why? jei ji išties tokia bloga, tai id = 1 OR id = 5 OR id = 169... geresnė?

Re: Preformancas: join vs. multi-query

Lukas wrote:

Tiesą sakant taip berods daro cakePHP freimworkas, o jis lyg ir prie geresnių yra priskiriamas. Reiks šiom dienom prisėsti ir giliau pažiūrėti, jei labai neužtingėsiu :D

Tai gali daryt, tokiu atveju vadinasi yra vietos optimizacijai.

Lukas wrote:

Iki šiol giliau neanalizavau, nes kiek reikėdavo, tai localhoste automatiškai sudarytos užklausos netrukdavo ilgiau 9-80ms įskaitant DESCRIBE (debug modas :)) ir keletą bereikalingų, be to nemačiau tikslo viską optimizuoti, juolab kad beveik visada galioja Pareto principas ir tam sugaištas nelabai atsipirktų.

80ms jau yra nemažai. čia aišku ne vien nuo užklausos priklauso, o ir nuo duomenų kiekio, jos sudėtingumo, schemos, kompiuterio galingumo ir t.t. ir t.t. Tik tiek, kad skaičiuojama, kad gerai yra kada VISA svetainė išgeneruojama per mažiau nei 0,3-0,2 sekundės.

Lukas wrote:

Beje jei neklystu, kažkur buvau matęs kad IN () yra gana lėta funkcija. Why? jei ji išties tokia bloga, tai id = 1 OR id = 5 OR id = 169... geresnė?

Kiekviena DBVS turi stiprių ir silpnų pusių. Kai mokoma SQL teorija tai ten apie optimizacijas ir specifiškus konkrečių DBVS niuansus niekas nekalba. Jeigu neklystu MySQL'e IN() veikia lėčiau negu sujungimas. Vienas dalykas yra tas, kad DBVS programuotojai optimizuoja programos darbą taip, kad jis veiktų kuo optimaliau. Sujungimas yra realiacinių duomenų bazių ašis ir jam optimizuoti yra skiriama labai daug dėmesio. Tuo tarpu IN() lieka nuošalyje. Plius yra kiti niuansai, tokie kaip pvz.: INDEX'as. Naudojant sujungimą labai efektyviai išnaudojami indeksai ir realiai turėtų būti taip, kad pradžioje panaudojant efektyvius algoritmus yra sujungiami indeksai, tada pagal jų rezultatą traukiami duomenys. IN() atveju, jeigu tu paduosi tarkim 10000 reikšmių (ne subužklausa, o tiesiog reikšmių masyvą) tai tos reikšmės neturės jokio indekso, jau vien dėlto pats sujungimas bus atliekamas lėtuoju būdu...

Jeigu reikšmių yra 3 tai tikriausiai nebus didelio skirtumo ar naudosi sujungimą, ar naudosi "IN(SELECT id..)" ar skaidysi per 2 užklausas ir naudosi "IN(1,2,3)" ar naudosi "OR id=1 OR id=2 OR id=3", nes bet kuriuo atveju bus sunaudojama mažai laiko. Realūs skirtumai pasimato prie didesnių duomenų kiekių, kurie pradeda netilpti į buferius/RAM ir pan. Bet kuriuo atveju visada pravartu pasitestuoti kelis galimus variantus, tik taip surasi ir suprasi kas yra geriau, o kas ne.

Re: Preformancas: join vs. multi-query

minde wrote:

IN() atveju, jeigu tu paduosi tarkim 10000 reikšmių (ne subužklausa, o tiesiog reikšmių masyvą) tai tos reikšmės neturės jokio indekso, jau vien dėlto pats sujungimas bus atliekamas lėtuoju būdu...

Apie šitai net nebūčiau pagalcvojęs :)


minde wrote:

Realūs skirtumai pasimato prie didesnių duomenų kiekių, kurie pradeda netilpti į buferius/RAM ir pan. Bet kuriuo atveju visada pravartu pasitestuoti kelis galimus variantus, tik taip surasi ir suprasi kas yra geriau, o kas ne.

Reiks testuojat prisidėti  punktą, pratestuoti tik su pvz 16-32mb ram palikus mysqlui

Re: Preformancas: join vs. multi-query

http://www.codersrevolution.com/index.c … -subselect

Re: Preformancas: join vs. multi-query

Siaip kiekteko skaityti, tai IN rekomenduoja naudoti kai buna daug reiksmiu, o kai yra keleteas reiksmiu, tai salyga geriau aprasyti su OR.