Autor | Zpráva | ||
---|---|---|---|
Prkny Profil |
#1 · Zasláno: 22. 7. 2012, 09:13:49
Zdravím, mám dotaz v mysql který trvá neúnosných 3,5 - 5 sec. Nevím jak jej zjednodušit a prosím o pomoc.
Dotaz prochází zboží v dané kategorii a hledá DISTINCTem jedinečné názvy parametrů, které jsou právě k danému zboží v té které kategorii. Příklad onoho dotazu: SELECT DISTINCT pzp.nazev, pzp.id, pzp.skupina FROM parametry_zb p, parametry_zb_prehled pzp WHERE p.id_zbozi IN ( SELECT z.id FROM zbozi z, zbozi_v_kat k WHERE z.id = k.id_zbozi AND z.vyradit = '' AND k.id_kat IN (SELECT id FROM kategorie WHERE (lft>'888') AND (rgt<'915')) ) AND pzp.id = p.id_parametru ORDER by pzp.nazev Ještě upřesím tabulky zbozi a zbozi_v_kat a kategorie jsou poměrně velké počtem záznamů. Ale tabulky parametry_zb a parametry_zb_prehled jsou zatím prakticky prázdné a přesto to takto dlouho trvá ... Můžete mi poradit ? |
||
Tori Profil |
#2 · Zasláno: 22. 7. 2012, 09:29:46
Zkuste ty poddotazy přepsat jako join:
SELECT DISTINCT pzp.nazev, pzp.id, pzp.skupina FROM parametry_zb p INNER JOIN parametry_zb_prehled pzp ON pzp.id = p.id_parametru INNER JOIN zbozi z ON z.id = p.id_zbozi INNER JOIN zbozi_v_kat k ON z.id = k.id_zbozi AND z.vyradit = '' INNER JOIN (SELECT id FROM kategorie WHERE (lft>'888') AND (rgt<'915')) ref ON k.id_kat = ref.id ORDER BY pzp.nazev Místo SELECT DISTINCT ... ORDER BY by asi šlo použít i SELECT ... GROUP BY pzp.nazev (seřazení je implicitní), ale nevím, jestli to bude mít nějaký vliv na rychlost, vyzkoušejte.
|
||
Keeehi Profil |
#3 · Zasláno: 22. 7. 2012, 09:33:47
Prkny:
Taky záleží na tom, zda jsou indexy nad správnými sloupci. |
||
Prkny Profil |
#4 · Zasláno: 22. 7. 2012, 12:47:06
Tori:
Váš dotaz razantně výsledek zrychlil, ale i přes to se dotaz provede za 0,7 sek. oproti 5 sekundám je to výborné, ale jelikož je to bude provádět na stránkách opravdu neustále asi by to chtělo ještě snížit. Pokud to vůbec ještě půjde. SELECT... nebo DISTINCT je často prakticky stejný.... GROUP BY nebo ORDER také stejně. Keeehi: Indexy moc řešené nejsou... moc se v návrhu indexu nevyznám... můžete mi dát nějaký tip ? |
||
Alphard Profil |
#5 · Zasláno: 22. 7. 2012, 13:10:34
Prkny:
Určitě si zobrazte explain, ale obecně indexy na sloupce, podle kterých se spojuje, řadí a filtruje. Zkusil bych je hodit na všechny sloupce, co mají v názvu id + lft, rgt a nazev. Jakých hodnot nabývá vyradit? |
||
Prkny Profil |
#6 · Zasláno: 22. 7. 2012, 18:14:29 · Upravil/a: Prkny
Alphard:
Parametr vyradit nabývá zatím pouze "out". Ten název je myšlen pro sloupec pzp.nazev ? Co také indexovat k.id_zbozi ? Alphard: Omlouvám se teť jsem si tu větu "všechny sloupce, co mají v názvu id" přečetl lépe, takže moje otázka je bezpředmětná. |
||
pcmanik Profil |
#7 · Zasláno: 22. 7. 2012, 18:27:01
Prkny:
Skus spustit explain nad tym dotazom a hod sem vypis. |
||
Prkny Profil |
#8 · Zasláno: 22. 7. 2012, 19:05:25
Alphard, Keeehi, Tori:
Pánové mnohokrát děkuji. Chyba byla především v indexech. Nyní mi ten dotaz běhá něco za 0,0027 sek. Takže nyní naprostá spokojenost. pcmanik: V tom explainu jsem se nikdy nenaučil číst mohu poprosit o letmou analýzu s vysvětlením ? http://imageshack.us/photo/my-images/401/20120722185836.jpg/ |
||
Tori Profil |
Prkny:
Jak koukám na ten explain, tak jsem tam nechala zbytečně tenhle poddotaz: INNER JOIN (SELECT id FROM kategorie WHERE (lft>'888') AND (rgt<'915')) ref ON k.id_kat = ref.id
Zkuste to změnit takhle: INNER JOIN kategorie kat ON k.id_kat = kat.id WHERE kat.lft > 888 AND kat.rgt < 915 ORDER BY pzp.nazev U tabulky parametry_zb se nepoužívá žádný index - měly by tam být 2, na sloupcích id_parametru a id_zbozi. |
||
Prkny Profil |
#10 · Zasláno: 22. 7. 2012, 20:55:12
Tori:
Díky, do tabulky parametry_zb jsem indexy doplnil. Jen pro informaci, díky vašim radám jsem se z 5 sek. dostal na 0,0028 sek. VŠEM DĚKUJI !!! |
||
Časová prodleva: 12 let
|
0