[ PavleK86 @ 12.05.2015. 12:05 ] @
Pozdrav svima!

Interesuje me šta sve utiče i šta predstavlja fetch time pri izvršavanju MySQL upita?

Imam upit čije je vrijeme izvršavanja relativno kratko, reda 0.15 sekundi. Međutim, fetch time je veoma dugo, oko 27 sekundi. Upit vraca nesto malo manje od 20k redova. Šta se može/mora uraditi da se fetch time svede na neku razumnu vrijednost, resimo 1 ili 2 sekunde?

Pretpostavljam da na ovo vrijeme ne utice sam upit, vec vjerovatno konfiguracija servera? U pitanju je MyISAM storage engine.

Unaprijed hvala,
Pavle
[ bogdan.kecman @ 12.05.2015. 12:19 ] @
fetch time je vreme da se rezultat posalje klijentu, dakle od mysql-a do
tebe, zavisi od toga koliko je opterecen klijent, kvalitet mreze izmedju
mysql-a i klijenta, velicine rezultata ..
[ PavleK86 @ 12.05.2015. 13:37 ] @
Bogdane,

Ako sam dobro shvatio, u ovom koraku se već dobavljeni redovi "samo" šalju klijentu, nema nikakvog čitanja sa diska, to je sve završeno u dijelu koji predstavlja duration?

Pokušao sam ovaj upit izvršiti direktno na mašini na kojoj je dignut MySQL server, slična je situacija, tako da nije nikakav problem u mreži. U nastavku je upit koji pokušavam izvršiti, mozda malo razjasni situaciju:

Code:

SELECT 
`a`.`id_podsklop_parent` AS `id_podsklop_parent`,
`a`.`id_podsklop_child` AS `id_podsklop_child`,
`a`.`kolicina` AS `kolicina2`,
`b`.`id_podsklop_child` AS `id_podsklop_child`,
`b`.`kolicina` AS `kolicina3`,
`c`.`id_komponenta` AS `id_komponenta`,
`c`.`kolicina` AS `kolicina`,
`x`.`opis` AS `opis`,
`x`.`id_grupa` AS `id_grupa`,
`x`.`id_jedinica` AS `id_jedinica`,
`x`.`cijena` AS `cijena`
FROM `proizvod_podsklop_sastav2` `a`
LEFT JOIN `proizvod_podsklop_sastav2` `b` ON `b`.`id_podsklop_parent` = `a`.`id_podsklop_child`
LEFT JOIN `proizvod_podsklop_sastav` `c` ON `c`.`id_podsklop` = `b`.`id_podsklop_child`
LEFT JOIN `komponenta` `x` ON `x`.`id` = `c`.`id_komponenta`


proizvod_podsklop_sastav [id | id_komponenta | kolicina] predstavlja sastav podsklopa koji se sastoji samo od komponenata
proizvod_podsklop_sastav2 [id_podklop_parent | id_podsklop_child | kolicina] predstavlja sastav podskopa preko drugih podsklopova

U aplikaciji sam definisao da je moguće da postoje samo 3 nivo podsklopova, tako da gornji upit vraća redove gdje su zastupljena sva 3 nivoa (parent, child i child od child-a).
[ bogdan.kecman @ 12.05.2015. 14:04 ] @
Citat:
PavleK86
Ako sam dobro shvatio, u ovom koraku se već dobavljeni redovi "samo" šalju klijentu, nema nikakvog čitanja sa diska, to je sve završeno u dijelu koji predstavlja duration?


i da i ne :D

malo je ta podela glupava ... zavrsena je exekucija upita ali ne znaci da se ne cita vise nista sa diska


Citat:
PavleK86:
Pokušao sam ovaj upit izvršiti direktno na mašini na kojoj je dignut MySQL server, slična je situacija, tako da nije nikakav problem u mreži. U nastavku je upit koji pokušavam izvršiti, mozda malo razjasni situaciju:


ne znaci mi upit nista bez EXPLAIN-a taj upit moze da se izvrsava 0.1sec a moze 1dan zavisno od toga koliko ima slogova, kakvi su indexi etc..

inace sam fetch time vs duration ti nije "dovoljno" precizan ako te zanima sta se stvarno desava

Code:

mysql> set profiling=1;
mysql> SELECT ....
mysql> SELECT  * FROM information_schema.profiling WHERE query_id=1;



[ bogdan.kecman @ 12.05.2015. 14:35 ] @
da ne zaboravim - brojke koje ti prikazuje mysql workbench su extremno odokativne!!! tako da ako hoces tacne brojke *moras* da ides sa profiling-om
[ PavleK86 @ 12.05.2015. 15:02 ] @
Evo ih:
Explain select
Profiling
[ bogdan.kecman @ 12.05.2015. 15:09 ] @
evo ti jedan mnogo dobar savet:

http://dom.as/2009/07/08/query-cache-tuning/
[ bogdan.kecman @ 12.05.2015. 15:15 ] @
koja ti je ovo verzija mysql-a ?
[ PavleK86 @ 12.05.2015. 15:25 ] @
5.1.44
[ bogdan.kecman @ 12.05.2015. 15:35 ] @
tebi ovde prosto traje upit toliko, ono ti je workbench pokazao svoje
odokativne brojek .. ovde se lepo vidi da ti exec radi 28 sekundi (exec
je iz dva dela, sending data je deo exec-a i za razliku od "fetching
data" nije samo "slanje rezultata" vec deo izvrsenja, vidis da je source
funkcije join::exec).

e sad, zasto je upit spor to je sada druga prica,
proizvod_podsklop_sastav2 mnozis ceo bez uslova sam sa sobom (dakle
3k3*3k3 slogova) i onda to mnozis sa par slogova iz c,x,p .. dakle ovde
uvek koristis celu proizvod_podsklop_sastav2 tabelu na kvadrat .. kako
ti raste ta tabela upit ce exponencijalno da se usporava. zar ne mozes
neki limit da dodas na to sta vuces iz proizvod_podsklop_sastav2 nekim
where-om?
[ bogdan.kecman @ 12.05.2015. 15:57 ] @
samo da razjasnim "executing" vs "sending data" posto je to vrlo cesto pitanje kada je mysql u pitanju i vrlo nejasno objasnjeno u dokumentaciji .. nadam se da ce ovo moje objasnjenje da bude malo jasnije

executing stage je stage u kome mysql, ako ima potrebe, kreira temp tabele
sending data stage je stage u kome mysql cita datu, filtrira slogove i salje ih klijentu (zato se zove sending.. posto mi cim nadjemo finalni slog odma ga saljemo klijentu)

scenario1:

select * from xyz;

dakle nema potrebe za nikakvim temp tabelama etc .. saljemo celu tabelu xyz. executing stage ne radi nista, traje 0.00.., sending data stage traje koliko treba da se procita tabela xyz sa diska i posalje sadrzaj iste na klijent. dakle skoro ceo execution time se nalazi u "sending data"

scenario2:

select * from xyz where nj = 7;

opet nema potrebe za nikakvim temp tabelama etc .. executing stage ne radi nista, traje 0.00.., sending data stage prolazi kroz tabelu (celu ako nj nije indexiran, samo kroz index ako je indexiran) i salje slogove kako nailazi na njih na klijent. dakle skoro ceo execution time se nalazi u "sending data"

scenario3:

select sum(x) from xyz where nj = 7;

opet ista prica kao scenario2, opet se sve nalazi u sending data

scenario4:

select sum(x) from xyz group by z;

e sad mysql mora da kreira temp tabelu, kreiranje temp tabele (citanje xyz tabele, sabiranje x po z) se desava u executing stage-u, kada se to zavrsi krece sending data stage koji sada cita tu temp tabelu i salje je na klijenta


scenario5:

select sum(x) as nj from xyz group by z having nj > 10;

isto kao s4 osim sto se nj > 10 deo izvrsava u sending data

nadam se da je malo jasnije
[ PavleK86 @ 22.05.2015. 01:03 ] @
Riješeno na "malo" drugaciji nacin. Ono što me je bunilo jeste što je Workbench to vrijeme prikazivao kao fetch, tako da nisam mogao ukapirati gdje je greška. Profiling usvojen :)
U svakom slučaju, hvala na pomoći i objašnjenju exec vs send data.

Pozdrav,
Pavle