Autor Zpráva
thingwath
Profil
Omlouvám se za ten titulek, ale nic lepšího mě nenapadlo.

Mám tabulku, kteřá krom dalšího smetí obsahuje sloupce id_kategorie, vl1 a vl2 (blbý nazvy, vím). Jde o tabulku článků v magazínu. Ve vl1 je měsíc vydání a ve vl2 rok vydání (opět souhlasím, že to není ideální). Já chci vybrat nejnovější číslo, mám na to dva různé dotazy:


SELECT vl1, vl2, obsah FROM clanky WHERE
vl1=(SELECT MAX(vl1) FROM clanky WHERE id_kategorie=333 AND
vl2=(SELECT MAX(vl2) FROM clanky WHERE id_kategorie=333))
AND vl2=(SELECT MAX(vl2) FROM clanky WHERE id_kategorie=333) AND id_kategorie=333;


Na pohled je to velmi ošklivé, tak jsem zkusil vykoumat něco lepšího:


SELECT MAX(vl2) AS vl2, MAX(vl1) AS vl1, obsah FROM clanky WHERE
id_kategorie=333 GROUP BY vl2 ORDER BY vl2 DESC;


Myslím, že to funguje. Ale to není důležité.

Podle očekávání je první dotaz mnohem pomalejší než ten druhý a to tak, že dost. Jenže problém je v tom, že když si nechám stránku vygenerovat stokrát s tím prvním, tak je to třikrát rychlejší. Zdá se totiž, že ten první pomalý dotaz se provede jednou a pak proběhne okamžitě, zatímco ten druhý si těch svých pár setinek vezme pokaždé.

Jde o MySQL 5.0.22.
nightfish
Profil
nefungovalo by něco ve stylu:
SELECT CONCAT(vl2, '-', vl1) as vydana, vl1, vl2, obsah FROM clanky ORDER BY vydana DESC LIMIT 0,1
thingwath
Profil
nightfish
Fungovalo by to, zdá se. Ale je to ještě pomalejší než ten můj první dotaz :-) A hlavně, nejde mi ani tak o to co funguje, spíš proč je ten pomalejší dotaz ve výsledku rychlejší.
DJ Miky
Profil
thingwath
To jsi to měřil v PMA?

A co třeba SELECT rok,mesic FROM clanky ORDER BY rok DESC, mesic DESC LIMIT 0,1 ? (obdoba nightfishova dotazu)
thingwath
Profil
Co mi ukáže konzole MySQL. Ale hlavní je u mě právě čas za který se mi povede vygenerovat sto stránek, to měřím skriptem.

Mně hlavně zajímá ten rozdíl o kterém jsem psal. Proč se ten první dotaz provádí jenom jednou (evidentně), zatímco ten druhý pokaždé.
Kajman_
Profil *
Asi se ten první cacheuje a druhý ne.

Osobně bych asi zkoušel prvně
SELECT vl1, vl2, obsah FROM clanky WHERE id_kategorie=333 ORDER BY vl2 DESC, vl1 DESC LIMIT 1
Samozřejmě s indexy na id_kategorie,vl2 a vl1.
thingwath
Profil
Což nějaká cache tam nejspíš určitě bude, ale zajímalo by mě proč. Tenhle dotaz vypadá rozumně. Budou tam asi až k desítkám tisíc článků (teď jich mám 5k a je to jenom neúplný vzorek dat) a celý zbytek toho systému je zoufale neefektivní a pomalý, takže se snažím zachránit co se dá.

Indexy jsou samozřejmost, i když už je tam index na id článku a fulltext index na jeho obsah. Na druhou stranu se budou přidávat velmi zřídka, tak to snad nevadí.
Kajman_
Profil *
Třeba příjde databázi ten první až tak složitý, že si ho uchová ;-)

Moc nevím, jaké jsou podmínky pro použití cache, ale určitě jde říct ručně, zda ji použít ...
SELECT [SQL_CACHE | SQL_NO_CACHE] ...
Toto téma je uzamčeno. Odpověď nelze zaslat.