Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Optimizacija upita, filesort, using temporary

[es] :: MySQL :: Optimizacija upita, filesort, using temporary

[ Pregleda: 1927 | Odgovora: 14 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

mb_sa

Član broj: 50529
Poruke: 172
89.146.186.*



Profil

icon Optimizacija upita, filesort, using temporary14.08.2009. u 09:16 - pre 179 meseci
Pozdrav.

http://rapidshare.com/files/266873156/testdev.sql.zip

Sa linka iznad mozete skinuti SQL fajl sa bazom i 3 tabele (njihova struktura i testni podaci).

Dakle, 3 tabele u kojima se čuvaju informacje o vijestima, kategorijama i autorima. Princip news sistema.

Napisao sam upit koji ispisuje 5 vijesti iz odredjene kategorija koja ima svoje potkategorije. Vijesti su soritrane po pozijama i vremenu objave ukoliko ne bude dovoljno vijesti kojima su označene pozicije, jer upit treba da vrati uvijek 5 redova.

Upit je ispod.

Code:
SELECT v.id, v.naslov, a.ime_prezime, v.mala_slika, v.uvod
FROM vijesti v, kategorije k, administratori a
WHERE k.kategorija_id = v.kategorija
AND v.autor = a.id
AND v.tip =1
AND v.media =0
AND v.pozicija
IN (
'5', '6', '7', '8', '9', '1000'
)
AND k.parent_id
IN ( 4, 5 )
AND v.id NOT
IN ( 22083, 22075, 22077, 22070 )
AND v.datum_objave <= '2009-08-13 10:58:00'
ORDER BY v.pozicija, v.datum_objave DESC
LIMIT 5


// ako je pozicija 1000, to znači da nema pozicije

Na bazu od 20.000 reedova upit se izvrsava u prosjeku nekih 0.3s sto mi je puno jer ovakih upita imam oko 10-tak na naslovnici (razlciite pozicije (v.pozicija) i kategorija (k.parent_id)).

EXPLAIN upita vraca: http://www.imagesforme.com/show.php/636527_explain.jpg

Ja sam stavio odredjne indexe (vidjećete kada ako pogledate sturkturu tabela iz priloga) koje MySQL i korsiti, tako da je kolona Rows u EXPLAIN tabele sasvim OK. Problem je očigledno kod onog što je napisano u EXTRA koloni.

Kada skinem index sa parent_id u tabeli kategorije, onda nema prolbema 'Using temporary', ali tada radi sa redovima citave tabele.

Mislim da bi se ovaj upit trebao brze zvrsavati, no za to mi je potrebna vasa pomoć? Imate li prijedloga kako da podesim indexe?

Nadam se da nisam nista propustio spomenuti.

Hvala unaprijed.

[Ovu poruku je menjao mb_sa dana 14.08.2009. u 14:20 GMT+1]
 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.31.24.217.adsl2.beograd.com.

Sajt: mysql.rs


+2377 Profil

icon Re: Optimizacija upita, filesort, using temporary14.08.2009. u 10:03 - pre 179 meseci
rapidshare link ne radi ... odnegde si radio copy/paste ... one tackice nisu sigurno deo linka ...
nisi napisao verziju mysql servera


 
Odgovor na temu

mb_sa

Član broj: 50529
Poruke: 172
89.146.186.*



Profil

icon Re: Optimizacija upita, filesort, using temporary14.08.2009. u 13:21 - pre 179 meseci
Citat:
bogdan.kecman: rapidshare link ne radi ... odnegde si radio copy/paste ... one tackice nisu sigurno deo linka ...
nisi napisao verziju mysql servera


Zdravo Bogdane.

Da, upravi si. Popravio sam link.

Ispod su osnove informacije o serveru. Hvala na izdvojenom vremenu.

MySQL

* Server: Localhost via UNIX socket
* Server version: 5.0.51a-3ubuntu5.4
* Protocol version: 10
* MySQL charset: UTF-8 Unicode (utf8)

Web server

* Apache
* MySQL client version: 5.0.51a
* PHP extension: mysql

 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.31.24.217.adsl2.beograd.com.

Sajt: mysql.rs


+2377 Profil

icon Re: Optimizacija upita, filesort, using temporary14.08.2009. u 13:36 - pre 179 meseci
vidim da su myisam tabele ... problem je sto imas po nekoliko slogova u ovoj test bazi, ne mozes da ocekujes da ce optimizer da radi kako treba na praznoj bazi (na ovakvoj bazi se ne isplati koristiti indexe uopste na primer - posto imaju po 10tak slogova tabele) ... jel mozes da napravis neki malo bolji test db .. (malo veci :D )

dodatno, bilo bi zgodno kad bi select o kome je rec vracao neke vrednosti iz "demo" baze?

nevezano za upit .. ako ti treba nekoliko ovakvih upita da izgenerises stranu - kesiraj stranu !!! (ili bar kesiraj upite - query_cache je majka za takve stvari)

upit na tvojoj tabeli traje (zacudzujuce :D ) 0.00 sec i daje ok explain ... upit moze (neznatno) bolje da se napise ali za to je potrebna bolja test baza i objasnjenje sta znaci ono IN ('5', '6', '7', '8', '9', '1000') .. u ovom tvom primeru ce optimizer (bar bi trebalo) to odraditi kao range scan ali pitanje sta tu "inace" moze da se nadje .. ako je "uvek" isti niz onda odradi od do + 1000 ...

sve u svemu, prepisivanje upita i menjanje strukture podataka je nemoguce na osnovu 6 redova u bazi .. kazes da ih ima 20K .. pusti mu neki md5 na stringove da s*s podatke i onda spucaj takvu bazu, ili izgenerisi neki random data .. ovako inicijalno .. osim onog in .. i sto bi mozda bilo iskusnije da koristis explicitno a ne implicitno join .. nema mnogo sta da se kaze
 
Odgovor na temu

mb_sa

Član broj: 50529
Poruke: 172
89.146.186.*



Profil

icon Re: Optimizacija upita, filesort, using temporary14.08.2009. u 13:59 - pre 179 meseci
Ovu sam bazu najvise postavio zobg strukture i tipova podataka. Izgenerisacu nekih neku sa vecim brojem redova, pa cuje postaviti.

@AND v.pozicija IN ('5', '6', '7', '8', '9', '1000')

Potrebno je da korisnici u admin panelu mogu da odrede poziciju na naslovnici. Takvih pozicija ima ukupno 16.

U jednom dijelu naslovnice potrebne su mi vijesti koje su na poziciji 5,6,7,8 i 9. Ponekad se desi da nema vijesti kojoj su dodijeljene pozicije, pa tada je potrebno da se ispisu najnovije (datum_obajve DESC). U drugom dijelu su mi potrebne sa pozcije 10, 11, 12 ...

Njih i mysql cache-ira i tada se izvrsavaju za 0.001 s (čim bude update nad tabelom, cache se brise). Neke od njih sam i planirao cache-irati sa PEAR Cache_Lite, ali ne mogu sve. Stranica je porplicno posjecena, pa bih volio srediti te upite kako valja.

Izgenerisacu bazu sa vecim brojem redova, pa cu se javiti.

Hvala puno na odgovorima.

 
Odgovor na temu

mb_sa

Član broj: 50529
Poruke: 172
89.146.186.*



Profil

icon Re: Optimizacija upita, filesort, using temporary14.08.2009. u 14:03 - pre 179 meseci
Zabravio sam jos reci. Ako tabela ima 20.000 vijesti, vrijednost kolone pozicija ce biti '1000' u vecini slucajeva, tacnije 19984 redova ce imati tu vriejdnost, preosltaih 16 ce imati brojeve u rasponu od 1-16.
 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.31.24.217.adsl2.beograd.com.

Sajt: mysql.rs


+2377 Profil

icon Re: Optimizacija upita, filesort, using temporary14.08.2009. u 14:32 - pre 179 meseci
dodaj posle select jedan SQL_NO_CACHE kako bi zaobisao kesh (ne na production serveru nego za test nad bekapom baze .. dakle da proverimo brzinu upita) .. pa odradi

Code:

SELECT SQL_NO_CACHE v.id, v.naslov, a.ime_prezime, v.mala_slika, v.uvod
FROM vijesti v, kategorije k, administratori a
WHERE k.kategorija_id = v.kategorija
AND v.autor = a.id
AND v.tip =1
AND v.media =0
AND v.pozicija
IN (
'5', '6', '7', '8', '9', '1000'
)
AND k.parent_id
IN ( 4, 5 )
AND v.id NOT
IN ( 22083, 22075, 22077, 22070 )
AND v.datum_objave <= '2009-08-13 10:58:00'
ORDER BY v.pozicija, v.datum_objave DESC
LIMIT 5


pusti ga 3-4 puta pa reci koliko traje upit ... a onda uradi sledece

Code:

SELECT SQL_NO_CACHE v.id, v.naslov, a.ime_prezime, v.mala_slika, v.uvod
FROM vijesti v, kategorije k, administratori a
WHERE k.kategorija_id = v.kategorija
AND v.autor = a.id
AND v.tip =1
AND v.media =0
AND v.pozicija
IN (
'5', '6', '7', '8', '9'
)
AND k.parent_id
IN ( 4, 5 )
AND v.id NOT
IN ( 22083, 22075, 22077, 22070 )
AND v.datum_objave <= '2009-08-13 10:58:00'
ORDER BY v.pozicija, v.datum_objave DESC
LIMIT 5


isto 3-4 puta .. pa daj brzine .. i na kraju ..


Code:

SELECT SQL_NO_CACHE v.id, v.naslov, a.ime_prezime, v.mala_slika, v.uvod
FROM vijesti v, kategorije k, administratori a
WHERE k.kategorija_id = v.kategorija
AND v.autor = a.id
AND v.tip =1
AND v.media =0
AND v.pozicija
IN (
'5', '6', '7', '8', '9'
)
AND k.parent_id
IN ( 4, 5 )
AND v.id NOT
IN ( 22083, 22075, 22077, 22070 )
AND v.datum_objave <= '2009-08-13 10:58:00'


3-4 puta .. pa brzine ...

tebe "dopunjavanje do 5" komada za slucaj kada ti fali neka pozicija vrlo verovatno "debelo kosta" tako da se mozda vise isplati da pokupis u 2 upita potrebne vrednosti ... dakle u jednom prolazu uzmes 5,6,7,8,9 i count(*) a onda u drugom prolazu ako ima potrebe uzmes jos onoliko koliko ti fali ..

generalno gledano, tebi query cache ovde radi posao .. bez obzira koliko je posecen sajt - sto poseceniji to bolje ... upiti su ti kesirani sve dok ne odradis update .. tj promenis sta treba da se nadje na naslovnoj - sto je regularno ... i opet, samo ce prvi ko cimne stranu da saceka 0.x sekundi za generisanje i opet imas sve upite kesirane ... doduse, 5.1 je malo bolji (ovaj poslednji) nego 5.0 posto 5.0 u nekim cudnim uslovima moze da se zabode pod velikim opterecenjem (odbodes ga sa "flush tables"). pritom - sa 20K slogova, tebi je cela ova tabela svejedno kesirana u ram-u ..

aj izgenerisi neke random podatke pa da probam par razlicitih promena nad samim upitom da vidimo sta moze tu jos da se uradi ... za pocetak radis order by pokoloni koja nije indexirana (to teoretski nevalja, prakticno nema nikakve razlike) ... imas 3x in .. to je sporo ... etc etc ... al .. sve je to nebitno dok se ne proba
 
Odgovor na temu

mb_sa

Član broj: 50529
Poruke: 172
89.146.176.*



Profil

icon Re: Optimizacija upita, filesort, using temporary14.08.2009. u 16:33 - pre 179 meseci
Ovo su brzine:

1. 0.35 s

2. 0.11 s

3. 0.09 s(par puta je islo na 0.1) u EXPLAIN nema filesort i using temporary

1,2 i 3 su upiti onim redoslijedom kojim si ti naveo. Poprlicno mi je jasno

Ne radi mi query cache bas posao, stranica se generise preko 4s, što je i tako kada izmjerim i saberem vrijeme svih ti upita. Dakle, generisanje je daleko ispod 1s. Bas cesto osjetim te spomenute 4 s.

Evo baze sa 20.000 redova: http://rapidshare.com/files/267336704/testdev_full.sql.zip.html (nadam se da ces je uspijeti skinuti, jer se izlgeda moze skinuti 10 puta)

Upiti se ovdje nesto brze izvrsavaju, vjerovatno jer vijesti nisu iste. Ali EXPLAIN vraca iste rezultate.

Hvala


 
Odgovor na temu

mb_sa

Član broj: 50529
Poruke: 172
89.146.176.*



Profil

icon Re: Optimizacija upita, filesort, using temporary14.08.2009. u 16:37 - pre 179 meseci
Jos jedno zapazenje ...

molim te obrati paznju na parent_id index kreiran na kategorije.parent_id. kada njega izbrisem, nema using temporary, ali tada radi sa svim redovima tabele.
 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.31.24.217.adsl2.beograd.com.

Sajt: mysql.rs


+2377 Profil

icon Re: Optimizacija upita, filesort, using temporary15.08.2009. u 06:00 - pre 179 meseci
ovako, prvo sto terba da uradis da bi dobio na brzini je:

Code:

-- napravi administratori tabelu da bude fixed
alter table administratori modify korisnicko_ime char(40), modify ime_prezime char(40);

-- napravi kategorije tabelu da bude fixed
alter table kategorije modify naziv char(40);

-- ista prica sa tabelom vijesti
-- ovde sada imas dupli problem, ajde sto je TEXT za "uvod" cinio tabelu "dynamic" 
-- (sto je za myisam dosta sporije od fixed) vec dodatno za svaki join sve kreirane 
-- temp tabele ce biti na disku sto je znacajno sporije nego u ram-u (bez obzira koliko mu 
-- das memorije za temp/heap tabele)
-- inace kada radis join UVEK se kreira temp tabela (bez obzira da li to explain prikaze ili ne)
-- 
-- ako ne mozes da smestis uvod u 255 karaktera, napravi zasebnu tabelu gde drzis uvod
-- pa ga povuci preko id-a kada budes morao ili ostavi TEXT ali onda konfigurisi server tako
-- da ti je tempdir na ram disku
alter table vijesti modify naslov char(100), modify mala_slika char(100), modify uvod char(255);


pre ove promene, sa ovom 20K slogova tabelom upit (iz originalnog posta) je trajao na mom desktopu izmedju 0.04 i 0.05 sekundi. posle ove promene (bez ikakve promene indexa / upita) upit traje 0.01 do 0.02sec

ako vratim uvod na TEXT brzina je 0.03 - 0.04

ako sada mysql namestim tako da u my.cnf dodam tmpdir=/dev/shm .. dakle kazem mu da koristi ram za mysql temp dir .. eh .. i nikakve promene ... 0.03 opet ...

jbg .. mnoooooooogo je brz .. sve to ispod 0.1sec je statisticka greska :) ... teba mi neka sporija masina za ovo testiranje :D

sve u svemu - osnovna sporost upita ti je u tome sto je v.uvod TEXT sto znaci da ce mysql da kreira temp tabelu na disku sto znaci da je upit sam po sebi ultra spor ... da bi to izbegao, ili izvbaci v.uvod iz upita ili ako moze da se uglavi u char(255) promeni ga u to, ili konfigurisi mysql da mu je tmpdir na ram disku kako bi zaobisao taj problem...

evo ga jedan "update vijesti set uvod=repeat(uvod, 10000);"

sada upiti traju malo duze :D

sa tmpdirom setovanim da pokazuje na /tmp (default) .. upit traje od 2.02 do 4.42sec zavisno od toga da li nesto drugo na masini trosi disk io... kada prebacim da je tmpdir na /dev/shm (ram disk) isti upit traje od 0.33 do 0.57sec

pritom, uzmi u obzir da masina "ne radi nista", dakle IO mi je free ... da imam konkurentne upite + neki apache koji drlja disk .. ovaj sa ram diskom bi ostao na 0.3-0.6sec dok bi onaj sto zavisi od io-a otisao na mnoooooooogo vise (pritom, ova masina ima 8G rama i ne radi nista trenutno dakle preko 4G rama je disk cache sto je dodatno pomoglo za onaj io bound query).


sad malo prebudzimo query ...

Code:

SELECT SQL_NO_CACHE
  v.id, v.naslov, a.ime_prezime, v.mala_slika, v.uvod
FROM 
  vijesti v 
  JOIN kategorije k ON (k.kategorija_id = v.kategorija) 
  JOIN administratori a ON (v.autor = a.id)

WHERE 
    v.tip = 1
AND v.media = 0
AND v.pozicija
IN ('5', '6', '7', '8', '9', '1000')
AND k.parent_id IN ( 4, 5 )
AND v.id NOT IN ( 22083, 22075, 22077, 22070 )
AND v.datum_objave <= '2009-08-13 10:58:00'
ORDER BY v.pozicija, v.datum_objave DESC
LIMIT 5;


isto to samo malo drugacije .. optimizer "manje pogadja" .. dobili smo ovde u proseku 0.1s ali onda ..

Code:

SELECT SQL_NO_CACHE
  v.id, v.naslov, a.ime_prezime, v.mala_slika, v.uvod
FROM 
  administratori a 
  JOIN vijesti v ON (v.autor = a.id)
  JOIN kategorije k ON (k.kategorija_id = v.kategorija) 


WHERE 
    v.tip = 1
AND v.media = 0
AND v.pozicija
IN ('5', '6', '7', '8', '9', '1000')
AND k.parent_id IN ( 4, 5 )
AND v.id NOT IN ( 22083, 22075, 22077, 22070 )
AND v.datum_objave <= '2009-08-13 10:58:00'
ORDER BY v.pozicija, v.datum_objave DESC
LIMIT 5;



i dobijemo ispod 2s

e sada "ovo nije normalno" :D ... dakle to je fora sto optimizer nekad ne odradi posao kako treba .... tako da realno to mozemo da zanemarimo :D ali je zgodno za spomenuti :D

ono sto je u celoj prici bitno je
Code:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: k
         type: range
possible_keys: PRIMARY,parent_id
          key: parent_id
      key_len: 4
          ref: NULL
         rows: 10
        Extra: Using where; Using temporary; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: v
         type: ref
possible_keys: PRIMARY,datum_objave,kategorija
          key: kategorija
      key_len: 4
          ref: es.k.kategorija_id
         rows: 435
        Extra: Using where
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: a
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: es.v.autor
         rows: 1
        Extra: 
3 rows in set (0.00 sec)


ovo nije optimalno ... da pogledamo upit sam za sebe ..

Code:

sta:  v.id, v.naslov, a.ime_prezime, v.mala_slika, v.uvod -- prvi problem, v.uvod je text znaci imamo temp tabele na disku

kako: 
v.autor = 
v.tip = 
v.media =
v.pozicija IN 
v.id NOT IN 
v.datum_objave <= 
v.kategorija = 

k.parent_id IN 
k.kategorija_id = v.kategorija

a.id =
sortiraj: v.pozicija, v.datum_objave


bez gledanja u tabele ... "ovde ima puno polja koja bi bilo zgodno da su indexirana" ... a mysql ne ume da koristi mnogo indexa u istom upitu ...

krenemo od pozadi ... administratori .. koristi se samo id .. on je primarni kljuc .. tabela ima tri ipo sloga .. dakle tu nista nema sta da se pipa ...

onda kategorije .. tu nam treba kompozitni kljuc, dakle
Code:

alter table kategorije modify kategorija_id int(5); 
alter table kategorije drop key parent_id;
alter table kategorije drop key naziv;
alter table kategorije drop primary key;
alter table kategorije add primary key (kategorija_id, parent_id);
alter table katogorije modify kategorija_id int(5) auto_increment;


dakle, sada tabela treba da izgleda:
Code:

mysql> show create table kategorije\G
*************************** 1. row ***************************
       Table: kategorije
Create Table: CREATE TABLE `kategorije` (
  `kategorija_id` int(5) NOT NULL AUTO_INCREMENT,
  `parent_id` int(5) NOT NULL DEFAULT '0',
  `naziv` char(40) DEFAULT NULL,
  PRIMARY KEY (`kategorija_id`,`parent_id`)
) ENGINE=MyISAM AUTO_INCREMENT=159 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


i sada upit traje 0.3sekunde ... dakle vise nego 10 puta krace ...

explain je blago drugaciji:
Code:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: v
         type: range
possible_keys: PRIMARY,datum_objave,kategorija
          key: datum_objave
      key_len: 9
          ref: NULL
         rows: 14185
        Extra: Using where; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: k
         type: ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: es.v.kategorija
         rows: 1
        Extra: Using where; Using index
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: a
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: es.v.autor
         rows: 1
        Extra: 
3 rows in set (0.00 sec)


sad nam jos ostaju vesti ...

da probamo najtruluju foru:
Code:

alter table vijesti add key (id, autor, tip, media, pozicija, datum_objave);


sta kaze explain:
Code:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: v
         type: range
possible_keys: PRIMARY,datum_objave,kategorija,id
          key: datum_objave
      key_len: 9
          ref: NULL
         rows: 14185
        Extra: Using where; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: k
         type: ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: es.v.kategorija
         rows: 1
        Extra: Using where; Using index
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: a
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: es.v.autor
         rows: 1
        Extra: 
3 rows in set (0.00 sec)


kaze da vidi nas key (id) ali nece da ga koristi ... aj da vidimo ocel biti nesto brze ako mu ga damo po forsiranju

Code:

mysql> explain SELECT SQL_NO_CACHE v.id, v.naslov, a.ime_prezime, v.mala_slika, v.uvod FROM vijesti v force key (id), kategorije k, administratori a WHERE k.kategorija_id = v.kategorija AND v.autor = a.id AND v.tip =1 AND v.media =0 AND v.pozicija IN ( '5', '6', '7', '8', '9', '1000' ) AND k.parent_id IN ( 4, 5 ) AND v.id NOT IN ( 22083, 22075, 22077, 22070 ) AND v.datum_objave <= '2009-08-13 10:58:00' ORDER BY v.pozicija, v.datum_objave DESC LIMIT 5\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: v
         type: range
possible_keys: id
          key: id
      key_len: 4
          ref: NULL
         rows: 20005
        Extra: Using where; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: k
         type: ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: es.v.kategorija
         rows: 1
        Extra: Using where; Using index
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: a
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: es.v.autor
         rows: 1
        Extra: 
3 rows in set (0.02 sec)

super .. force radi, znamo sintaksu :D .. ali da li ima razlike u brzini:

ima .. malopre je bio 0.3 sad je 0.36-0.4 .. znaci sporo ... da probamo malo da promenimo redosled ...

Code:

alter table vijesti add key kljuc2 (datum_objave, id, autor, tip, media, pozicija);

SELECT SQL_NO_CACHE v.id, v.naslov, a.ime_prezime, v.mala_slika, v.uvod FROM vijesti v force key (kljuc2), kategorije k, administratori a WHERE k.kategorija_id = v.kategorija AND v.autor = a.id AND v.tip =1 AND v.media =0 AND v.pozicija IN ( '5', '6', '7', '8', '9', '1000' ) AND k.parent_id IN ( 4, 5 ) AND v.id NOT IN ( 22083, 22075, 22077, 22070 ) AND v.datum_objave <= '2009-08-13 10:58:00' ORDER BY v.pozicija, v.datum_objave DESC LIMIT 5\G


tu smo negde na 0.3 - 0.33 ...

sada tu mozes da se igras .. realno zgodno je da tu imas kljuc koji za prvo polje ima EQ koji najvise filtrira tabelu (dakle na primer ako ce tip da izbaci 90% kolona iz rezultata - njega stavis prvog ... range polja stavis poslednja - kao na primer ovaj datum) ..

elem .. imamo ga sada (bez hintova i bez ovog velikog kljuca) na 0.3 ... (jos uvek smo sa temp diskom na /tmp) ... sve to isto samo tmpdir stavimo na ram disk i brzina je: 0.09s




 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.31.24.217.adsl2.beograd.com.

Sajt: mysql.rs


+2377 Profil

icon Re: Optimizacija upita, filesort, using temporary15.08.2009. u 06:13 - pre 179 meseci
zakljucak ...

promena u strukturi tabela
Code:

alter table administratori modify korisnicko_ime char(40), modify ime_prezime char(40);

alter table kategorije modify naziv char(40);

alter table kategorije modify kategorija_id int(5); 
alter table kategorije drop key parent_id;
-- alter table kategorije drop key naziv; -- ovo nam ne smeta ovde, ako ti negde treba ostavi ga
alter table kategorije drop primary key;
alter table kategorije add primary key (kategorija_id, parent_id);
alter table katogorije modify kategorija_id int(5) auto_increment;

alter table vijesti modify naslov char(100), modify mala_slika char(100);
-- alter table vijesti modify uvod char(255); -- mozda neizvodljivo


promena u konfiguraciji mysql-a
1. setovati tmpdir da pokazuje na ram disk (default na linuxu /dev/shm postoji ram disk vec mountovan)
2. povecaj sort buffer size http://dev.mysql.com/doc/refma...s.html#sysvar_sort_buffer_size znacajno
3. povecaj key_buffer_size (na ~30-35% od ukupne kolicine rama)
4. imas jos hintova ovde: http://www.mysql.rs/2009/03/optimizacija-mysql-servera/


sve ostalo zahteva menjajne koncepta .. samim tim sto dodajes 1000 u poziciju, uvlacis previse slogova u rezultat i onda svi ti slogovi treba da se sortiraju i tek onda uzmes prvih 5 ... nije bas idealno resenje ... ako mozes da izbacis 1000 i onda iz tvog php-a (jesam dobro razumeo, app je neki php) pokupis broj redova koje si dobio (mysql_num_rows() ako se dobro secam) u rezultatu pa ako je manji od ocekivanog povuces jos jedan upit sa 1000 i pokupis tih par komada koliko ti fali .... ovako je super sto to dobijes u jednom upitu ali je upit mnogo sporiji nego sto mora da bude samo zbog toga...

nadam se da ti cela ova prica pomaze ... prethodni post sam ja kucao kako sam probao razne stvari, nadam se da je informativan ..
 
Odgovor na temu

mb_sa

Član broj: 50529
Poruke: 172
89.146.164.*



Profil

icon Re: Optimizacija upita, filesort, using temporary16.08.2009. u 08:47 - pre 178 meseci
Bogdane, hvala velika na pomoci i opsirnim komentarima.

Sredio sam da sva polja budu CHAR (mislio sam da to donosi samo poboljsanja ako se pretrazuje po njima), osim uvod kojeg ne mogu strpati u 255 karaktera.

Izgleda da cu najvise dobiti prebacivanjem na ram disk. Zanima me da li to moze stvoriti bilo kakve dodatne probleme? Postoje li situacije kada je bolje ostaviti sve na disku?

Takodjer, vjeroavno cu i dobiti ako upit podjelim na dva brza upita, kao sto si predlagao.

Hvala puno na pomoci i izdvojenom vremenu.

Pozdrav.
 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.31.24.217.adsl2.beograd.com.

Sajt: mysql.rs


+2377 Profil

icon Re: Optimizacija upita, filesort, using temporary16.08.2009. u 09:27 - pre 178 meseci
Citat:
mb_sa
Sredio sam da sva polja budu CHAR (mislio sam da to donosi samo poboljsanja ako se pretrazuje po njima)

za innodb nema nikakve razlike, za myisam ima veze za sve i za select i za insert i za update - ali nije razlika u varchar vs char nego u fixed vs dynamic table, ako je tabela dynamic potpuno je nebitno da li su neka polja onda varchar ili char ..

Citat:

, osim uvod kojeg ne mogu strpati u 255 karaktera.


da tu ne mozes nista da promenis to je sto je ... ali obrati paznju da zbog toga sto je to blob upit pravi temp tabele na disku (svaki join *uvek* pravi temp tabele bez obzira da li to explain napise ili ne).

Citat:

Izgleda da cu najvise dobiti prebacivanjem na ram disk. Zanima me da li to moze stvoriti bilo kakve dodatne probleme? Postoje li situacije kada je bolje ostaviti sve na disku?


bas tako - posto ti je to osnova problema sa kojim se suocavas - prave ti se temp tabele na disku .. situacije kada je bolje da imas temp tabele na disku .. paaaaa .. nemas dovoljno rama :D .. to je jedini razlog da ne stavis temp tabele na ram disk

Citat:

Takodjer, vjeroavno cu i dobiti ako upit podjelim na dva brza upita, kao sto si predlagao.


yup. izbacivanjem 1000 iz upita ti iz tabele od 20K slogova trazis 5 slogova koji su indexirani - to traje "nista" vremena ... a onda "po potrebi" pokupis koliko ti jos fali ... cesto ces videti da se u slicnim situacijama koristi ajax tako sto ti posaljes onoliko vesti koliko imas a onda strana "pozove" dodatno koliko joj vesti traje kada se ucita tako da klijent "odma" dobije prvih X vesti a ostale mu se ucitaju posle par stotina milisekundi...

sve u svemu, znas gde su ti uska grla, imas neke ideje kako da ih zaobidjes / promenis .. promena kljuca na kategorijama je kod mene donela veliki napredak u brzini (onaj kompozitni kljuc) .. treba probati na realnim podacima ..
 
Odgovor na temu

mb_sa

Član broj: 50529
Poruke: 172
*.PPPoE-1175.sa.bih.net.ba.



Profil

icon Re: Optimizacija upita, filesort, using temporary30.08.2009. u 15:39 - pre 178 meseci
Zdravo Bogdane!

Evo da javim sta se je desilo, vjerujm da ce i drugima biti od pomoci.

Povecanje sort i key buffera je pomoglo, ali problem ovog upita je bio "ORDER by pozicija, datum_objave DESC". Što sam i ranije pročitao u mysql dokmnetaciji, ali bez povecanog sort i key buffera izgleda da ni DESC DESC ili ASC ASC sortiranje nije pomagalo.

Dakle, mysql ne zna da korsiti index ukoliko miksamo ASC i DESC, što je bio kod mene slučaj. Promjena upita na ORDER by pozicija DESC, datum_objave DESC uz kreiran index (pozicija,datum_objave) jer radila dalekoooo brze (reda 0.0010s).

Mejdutim, prolbem je sto vo ne vraca željene rezultate. U tabelu sam dodao pozicija_reverse koja je sadrzava suprotne vrijednosti, tako da sam mogao da sortiram po principu pozicjija DESC, datum_obajve DESC. Naravno kreiran je index za (pozicija_reverse,datum_obajve) i upit se izvrsava za 0.0010.

Povecanje key buffer size sort buffer size je pomoglo da korsiti index (pozicija,datum_objave) tako da je pomoglo i kod ovog upita i generlano kod upita koji su imali samo sortiranje po datumu.

Prebacivanje na ram disk iz nekog razloga nije pomoglo, tako da smo za sada ostavili na disku sve.

Hvala na pomoci i sve najbolje!


 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.31.24.217.adsl2.beograd.com.

Sajt: mysql.rs


+2377 Profil

icon Re: Optimizacija upita, filesort, using temporary31.08.2009. u 07:50 - pre 178 meseci
Citat:
mb_sa
Povecanje sort i key buffera je pomoglo, ali problem ovog upita je bio "ORDER by pozicija, datum_objave DESC". Što sam i ranije pročitao u mysql dokmnetaciji, ali bez povecanog sort i key buffera izgleda da ni DESC DESC ili ASC ASC sortiranje nije pomagalo.

Dakle, mysql ne zna da korsiti index ukoliko miksamo ASC i DESC, što je bio kod mene slučaj. Promjena upita na ORDER by pozicija DESC, datum_objave DESC uz kreiran index (pozicija,datum_objave) jer radila dalekoooo brze (reda 0.0010s).


skroz sam preskocio da koristis asc,desc u tvom upitu :( .. super da si provalio to .. valjda ce jos nekom da koristi
 
Odgovor na temu

[es] :: MySQL :: Optimizacija upita, filesort, using temporary

[ Pregleda: 1927 | Odgovora: 14 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.