Zadejte hledaný výraz...

MySQL rychlejší select

mcever4
verified
rating uzivatele
10. 4. 2010 09:07:05
Zdravím, potřeboval bych poradit s jedním selektem.
mám dvě tabulky INZERATY, FOTO relace 1:N
inzeratu je cca 60tisíc, fotografií přes milion
tabulka INZERAT (id,nazev)
tabulka FOTO (id_foto, id_inzerat, link_foto)
potřebuji vypsat vsechny inzeráty a ke kazdemu jen jednu fotku s nejmensim ID.
kdyz pouziju JOIN LEFT, tak mi to udelá kartézský součin a musím použít group by inzerat.id
pak ale nedokážu, aby se načetla fotka s nejmensim foto.id.
jinak group by zpomaluje dost nacitani.
SELECT * FROM inzerat LEFT JOIN foto ON inzerat.id=foto.id_inzerat WHERE 1 group by inzerat.id
pokud pouziji tento zápis
SELECT inzerat.id, (select foto.link_m from foto where inzerat.id=foto.id_inzerat order by foto.id LIMIT 1) as fotka
FROM inzerat
pak dotaz trvá přes 5vteřin
poznámka: indexy na sloupcích které porovnávám mám nastavené
jsou ještě nějaké jiné způsoby?
10. 4. 2010 09:07:05
https://webtrh.cz/diskuse/mysql-rychlejsi-select#reply488539
Mgr. Ivo Toman
verified
rating uzivatele
(7 hodnocení)
11. 4. 2010 10:13:31
A nepomohlo by něco takového?
SELECT i.*, MIN(f.id) FROM inzerat i
LEFT JOIN foto f ON i.id=f.id_inzerat
group by i.id
11. 4. 2010 10:13:31
https://webtrh.cz/diskuse/mysql-rychlejsi-select#reply488538
Gimli
verified
rating uzivatele
11. 4. 2010 10:27:58
a co použít kombinaci těch dvou:
SELECT *
FROM inzerat
LEFT JOIN foto ON inzerat.id=foto.id_inzerat
ORDER BY id_foto ASC
LIMIT 1
11. 4. 2010 10:27:58
https://webtrh.cz/diskuse/mysql-rychlejsi-select#reply488537
mcever4
verified
rating uzivatele
11. 4. 2010 10:57:07
Díky, jen bych potřeboval doladit drobnost
pokud bych chtěl vypsat i název fotky, tak min ID funguje a je to id fotky s nejmensim ID, ale nazev fotky s maximálním id
SELECT i.*, MIN(f.id), f.nazev_fotky FROM inzerat i
LEFT JOIN foto f ON i.id=f.id_inzerat
group by i.id
11. 4. 2010 10:57:07
https://webtrh.cz/diskuse/mysql-rychlejsi-select#reply488536
duben
verified
rating uzivatele
(49 hodnocení)
11. 4. 2010 11:33:48
V tomhle případě, při takovém množství záznamů a potřebu rychlosti si denormalizuj databázi. Udělej novou tabulku InzeratFoto, kam dej pole id_inzerat, id_foto, nazev_fotky. Při uložení nové fotky aktualizuj název v denormalizované tabulce. Index dej kombinovany na id_inzerat, id_foto. Výrazně se tím urychlíš provádění dotazu. Není problém to pak joinovat na tabulku Inzerat a eliminujes narocnost joinování s tabulkou FOTO.
A pokud ti jde o optimalizaci dotazu, tak se nauč přestat používat ve finálních dotazech SELECT *. Vypisuj jen pole která opravdu potřebuješ.
11. 4. 2010 11:33:48
https://webtrh.cz/diskuse/mysql-rychlejsi-select#reply488535
hm
verified
rating uzivatele
(20 hodnocení)
12. 4. 2010 03:45:58
Napsal duben;493713
V tomhle případě, při takovém množství záznamů a potřebu rychlosti si denormalizuj databázi. Udělej novou tabulku InzeratFoto, kam dej pole id_inzerat, id_foto, nazev_fotky. Při uložení nové fotky aktualizuj název v denormalizované tabulce. Index dej kombinovany na id_inzerat, id_foto. Výrazně se tím urychlíš provádění dotazu. Není problém to pak joinovat na tabulku Inzerat a eliminujes narocnost joinování s tabulkou FOTO.
A pokud ti jde o optimalizaci dotazu, tak se nauč přestat používat ve finálních dotazech SELECT *. Vypisuj jen pole která opravdu potřebuješ.
otazka je zda to na trech sloupcich udela nejaky rozdil :) select * pouzivam a presto jsou moje dotazy optimalni (kdyz mam tabulku se tremi sloupcemi a sloupce pouziji, proc nepouzit * misto vypisovani vsech sloupcu), samozrejme neoc jineho je to u vetsi tabulky ze ktere vsechny data nevyuziji
12. 4. 2010 03:45:58
https://webtrh.cz/diskuse/mysql-rychlejsi-select#reply488534
grey
verified
rating uzivatele
12. 4. 2010 07:35:19
Napsal AlesiBoss;494578
otazka je zda to na trech sloupcich udela nejaky rozdil :) select * pouzivam a presto jsou moje dotazy optimalni (kdyz mam tabulku se tremi sloupcemi a sloupce pouziji, proc nepouzit * misto vypisovani vsech sloupcu), samozrejme neoc jineho je to u vetsi tabulky ze ktere vsechny data nevyuziji
tak třeba pro přehled? když to po tobě bude číst někdo jiný?
12. 4. 2010 07:35:19
https://webtrh.cz/diskuse/mysql-rychlejsi-select#reply488533
duben
verified
rating uzivatele
(49 hodnocení)
12. 4. 2010 12:28:03
Aleši udělá to rozdíl vždy. Pokud máš tabulku se 3 sloupci a chceš je vypsat stejně všechny 3, tak rozdíly které nastanou přímo a nepřímo:
1. Výkonová úspora, pokud dáš Select * tak interní DB engine řeší tyhle kroky: nejdřív musí zjistit jaké všechny sloupce tabulka obsahuje, jeden po druhém je seřadit za sebou (tj. interně vygenerovat select se sloupci) a to pak zobrazit. Pokud dáš místo toho rovnou vypsané sloupce jen prostě provede select a vypíše zadané sloupce. Takže ušetříš minimálně jeden mezikrok. To, že se ti to na 1 dotazu neprojeví, neznamená, že tvoje dotazy jsou optimalní. SELECT *, není optimální forma dotazu nikdy.
2. Úspora do budoucna. DB model se obvykle vyvíjí. Takže v budoucnu se třeba přidají další sloupce, to pro tebe znamená, že:
a) taháš sloupce navíc a tak se mezi DB serverem a Aplikačním serverem tahají zbytečně data navíc, která nejsou potřeba
b) půjdeš zpátky do kódu a změníš SELECT * na výpis sloupců. Je to zbytečný vývojový čas navíc, může nastat chyba v kódu překlepem, můžeš zjistit, že nějaké další sloupce používá z tvého selectu někdo jiný, kdo upravoval kód po tobě apod.
Lenost nahradit * seznamem vypsaných sloupců se prodraží minimálně stejně jako lenost nepsaní komentářů do zdrojáků a do kódu.
12. 4. 2010 12:28:03
https://webtrh.cz/diskuse/mysql-rychlejsi-select#reply488532
Pro odpověď se přihlašte.
Přihlásit