Pohitritev querija
3 naročniki
3 naročniki
Kako pohitriti poizvedbo?
Showing rows 0 - 20 (21 total, Query took 1.5251 sec)
SELECT n.title, n.news_id, n.short, n.picture, n.youtube, n.audio, n.gallery_id, n.inserted
FROM news AS n
LEFT JOIN news2category AS n2c ON ( n2c.news_id = n.news_id )
WHERE n2c.category_id = '5'
AND n.inserted < NOW( )
ORDER BY n.priority DESC , n.inserted DESC
LIMIT 0 , 21
Index je nastavljen na fieldih: news_id, priotity, inserted
V povezovalni tabeli je vse indeksirano.
Novic je v bazi cca 30000
Zadevo upočasni ORDER BY, brez sortiranja dobim rezultat v 0.00x sekundah.
HELP :)
11 odgovorov
zakaj imaš LEFT JOIN? navaden join ne bi bil v redu? A je pogoj n.inserted < NOW() smiseln? Če nimaš insertov v prihodnosti, to odstrani.
MySQL uporabi samo 1 index na posamezno aktivno tabelo v queryju. EXPLAIN pokaže, da izbere PRIMARY index za tabelo news. Na tej tabeli ti izvajaš sledeče operacije: WHERE (polje inserted), ORDER (priority in inserted). Mogoče je torej boljši index inserted, kar lahko sforsiraš (išči FORCE INDEX), lahko pa probaš tudi forsirati index na priority (čeprav dvomim, da bo bolje).
Za tabelo news2category izbere index categoryid, vendar to pomeni, da mora delati scan tabele za pogoj n2c.newsid = n.newsid, namesto da bi poiskal z indexom. Probaj spremeniti zadevo v navaden join in forsirati index newsid za tabelo n2c.
Tole je takole na hitro na pamet. Drugače pa 1.5 sekunde ni čas za sekiranje. :)
Še nisem videl tvojega posta, ko sem odkril FORCE INDEX in USE INDEX.
LEFT sem odstranil, ne opazim razlike.
NOW() je potreben, ker so novice napisane za v naprej.
Najbolje se obnese, če forcam(ali USE) index na priority. Sedaj se izvede v 0.1~0.2 sekunde !
Hvala za odgovor!
zmagovalni query: 0.06s
SELECT n.title, n.news_id, n.short, n.picture, n.youtube, n.audio, n.gallery_id, n.inserted
FROM news AS n
FORCE INDEX ( priority )
JOIN news2category AS n2c
FORCE INDEX FOR JOIN (
news_id
) ON ( n2c.news_id = n.news_id )
WHERE n2c.category_id = '5'
AND n.inserted < NOW( )
ORDER BY n.priority DESC , n.inserted DESC
LIMIT 0 , 21
fatg, kapo dol :)
Kadar imam LIMIT 0, 20
se izvede v 0.2 sekunde,
pri npr. LIMIT 450, 20
se pa izvaja 1.2 sekunde.
Se da še tu kaj pridobit?
mogoče boš še kaj profitiral s force index (inserted), na pamet pa težko kaj več svetujem. Čas se očitno izgublja pri sortiranju, zato morda namesto single indexa na priority ustvari kompoziten index na (priority, inserted) ali (inserted, priority) in potem forsiraj tega. Lahko probaš tudi s kompozitnim indexom (newsid, categoryid) ali (categoryid, newsid) na news2category tabeli.
ena varianta je tudi z uporabo STRAIGHT_JOIN
SELECT STRAIGHTJOIN n.title, n.newsid, n.short, n.picture, n.youtube, n.audio, n.galleryid, n.inserted
FROM news AS n
LEFT JOIN news2category AS n2c ON ( n2c.newsid = n.newsid )
WHERE n2c.categoryid = '5'
AND n.inserted < NOW( )
ORDER BY n.priority DESC , n.inserted DESC
LIMIT 0 , 21
dej please sporoči kolk hitr bo query k me zanima ! Če sploh bo kej pohitril ;)
LP
Armando
armandoxxx: Časi izvedbe nihajo, mislim pa da je v popvprečju tvoja varjanta počasnejša za cca 50% - škoda
FORCE INDEX FOR JOIN zmaga :)