Pohitritev querija

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.

explain:

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. :)

5

FORCE INDEX(inserted, priority) je spravlo zadevo na 0.2 ~ 0.4 sekunde

1

Š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 :)

no, krasno :)

2

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.

4

S kopozitnimi indexi mi žal ni uspelo, sem pa uredil cachiranje querijev tako da zdaj gre kot mora.

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.news
id = n.newsid )
WHERE n2c.category
id = '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 :)