Nee ok, alleen op kolommen waarop je selecteert of sorteert is een betere benaming.quote:Op donderdag 2 maart 2006 21:55 schreef JeRa het volgende:
[..]
Niet bij álle foreign keys, maar het is een goede vuistregel ja. Voorbeeldje waarbij het niet moet; als je voor een fotoalbum drie groottes van een bepaalde foto hebt kun je die drie groottes in één record laten verwijzen naar drie foreign records, maar daar hoeft in principe helemaal geen index op omdat je daar nooit op selecteert of sorteert.
Van mysql.org:quote:In álle gevallen worden INSERTs trager door indices, en als het goed is kan MySQL zelf prima bepalen of het een index gebruikt of nietdus wat dat betreft zal het niet trager worden.
MySQL staat nou niet echt goed bekend om z'n query optimalisatie kwaliteiten.quote:Op donderdag 2 maart 2006 21:55 schreef JeRa het volgende:
en als het goed is kan MySQL zelf prima bepalen of het een index gebruikt of niet
In jouw voorbeeld zie ik één query die alle rows aandoet en die sorteert op first_price; die zou je prima kunnen indexeren.quote:Op donderdag 2 maart 2006 22:05 schreef Swetsenegger het volgende:
Maar ja, in bovenstaand voorbeeld heb ik regelmatig ALLE product rows nodig. Zijn indexes dan aan te raden of niet?
Dat weet ik, ik ga er altijd vanuit dat ze dat in de toekomst nog kunnen verbeteren terwijl de queries hetzelfde blijven. Als het een probleem wordt schakel ik over op een andere DBMS die dat wel kan bepalenquote:Op donderdag 2 maart 2006 22:10 schreef SuperRembo het volgende:
[..]
MySQL staat nou niet echt goed bekend om z'n query optimalisatie kwaliteiten.
First price heb ik inderdaad nu geindexeerd.quote:Op donderdag 2 maart 2006 23:14 schreef JeRa het volgende:
[..]
In jouw voorbeeld zie ik één query die alle rows aandoet en die sorteert op first_price; die zou je prima kunnen indexeren.
[..]
Dat weet ik, ik ga er altijd vanuit dat ze dat in de toekomst nog kunnen verbeteren terwijl de queries hetzelfde blijven. Als het een probleem wordt schakel ik over op een andere DBMS die dat wel kan bepalen
Laat eens zien?quote:Op vrijdag 3 maart 2006 11:04 schreef Swetsenegger het volgende:
Ik heb een mooie query van Super Rembo, welke 3 laatste records per catagorie uit de database trekt.
Alleen duurt deze query tussen de 15(!) en 0.0003 seconden. De eerste keer doet hij er meestal heel lang over, de tweede keer korter.
Ik mag toch aannemen dat dat aan de hoster ligt?
De Query?quote:
1 2 3 4 5 6 7 | FROM genre g INNER JOIN ad a ON a.genre = g.genre_id INNER JOIN ad a2 ON a2.genre = g.genre_id AND a.ad_id <= a2.ad_id GROUP BY a.ad_id HAVING COUNT(a2.ad_id) <= 3 ORDER BY g.genre_id, a.ad_id DESC |
Wat anders?quote:
Dit is een mooi voorbeeld van een query die géén indices gebruikt maar de tweede keer snel wordt door het gebruik van de query cache op de server. Ik zie zo even niet waarom hij ze niet gebruikt.quote:Op vrijdag 3 maart 2006 11:04 schreef Swetsenegger het volgende:
Alleen duurt deze query tussen de 15(!) en 0.0003 seconden. De eerste keer doet hij er meestal heel lang over, de tweede keer korter.
Ja, als ik de GROUP BY aanpas naar bv a.title is hij de eerste keer weer traag.quote:Op vrijdag 3 maart 2006 14:31 schreef JeRa het volgende:
[..]
Dit is een mooi voorbeeld van een query die géén indices gebruikt maar de tweede keer snel wordt door het gebruik van de query cache op de server. Ik zie zo even niet waarom hij ze niet gebruikt.
Als het goed is zou je door iets te veranderen in één van de tabellen de query uit de query cache kunnen halen, is hij dan weer zo traag?
ongeveer 2000 records in de ad table, 19 in de genre tabel en een stuk of 100 in de user tabel. ALlemaal niet erg spannendquote:Op vrijdag 3 maart 2006 14:48 schreef Scorpie het volgende:
Hm ik zie zo 1,2,3 niet in waarom hij zo lang moet laden...heel apart. Hoeveel data bevatten de tabellen?
Om voor testing purposes de query cache eventjes te omzeilen zou je SQL_NO_CACHE kunnen gebruiken, zie deze pagina.quote:Op vrijdag 3 maart 2006 14:49 schreef Swetsenegger het volgende:
[..]
Ja, als ik de GROUP BY aanpas naar bv a.title is hij de eerste keer weer traag.
Ik vreesde ook al dat de query daadwerkelijk traag is en de tweede keer uit cache komt
Je GROUP BY is trouwens niet helemaal goed. Alle velden die je in de SELECT gebruikt en die je niet in een aggregate functie hebt staan, moeten in de GROUP BY worden opgenomen. MySQL accepteerd het wel als je dat niet doet, maar dat kan tot onvoorspelbare resultaten leiden. Zo zou het moeten:quote:Op vrijdag 3 maart 2006 11:13 schreef Swetsenegger het volgende:
[..]
De Query?
[ code verwijderd ]
-edit-
indices op a.ad_id (PK), a.genre, g.genre_id (PK)
1 |
1 |
De aggregate functie is... het optel gebeuren?quote:Op vrijdag 3 maart 2006 15:40 schreef SuperRembo het volgende:
[..]
Je GROUP BY is trouwens niet helemaal goed. Alle velden die je in de SELECT gebruikt en die je niet in een aggregate functie hebt staan, moeten in de GROUP BY worden opgenomen. MySQL accepteerd het wel als je dat niet doet, maar dat kan tot onvoorspelbare resultaten leiden. Zo zou het moeten:
[ code verwijderd ]
Eventueel zou je alleen de PK's op kunnen nemen. Dan zijn de resultaten voorspelbaar maar misschien is het ietsje sneller
[ code verwijderd ]
Hier begrijp ik niets van.quote:Op vrijdag 3 maart 2006 17:23 schreef SuperRembo het volgende:
Ik weet niet in welke volgorde MySQL die joins uitvoert. Met een beetje pech begint MySQL met de join van ad op ad. Die geeft 2000 * 2000 / 2 = 2000000 rows.
Dat dacht ik ook.quote:Op vrijdag 3 maart 2006 18:06 schreef JeRa het volgende:
Zelfs dan zou het niet zó lang mogen duren, toch? Een query op een tabel met 10.000 rows die ik op zichzelf laat joinen is in een fractie van een seconde gedaan.
1 2 3 4 5 | FROM ad WHERE genre=1 ORDER BY ad_id DESC LIMIT 3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $queryMain="SELECT * FROM genre"; $resultMain=mysql_query($queryMain); while($rowMain=mysql_fetch_assoc($resultMain)){ $querySub="SELECT title, ad_id, image, price FROM ad WHERE genre=".$rowMain['genre_id']." ORDER BY ad_id DESC LIMIT 3"; $resultSub=mysql_query($querySub); while($rowSub=mysql_fetch_assoc($resultSub)){ // doe iets } } ?> |
Ik moet toe geven dat het stiekum toch een draak van een query is. Ik heb ff een testje gedraaid met een tabel met 10000 rows... daarmee legde MySQL m'n pc 16 minuten plat. MSSQL deed het met dezelfde data in 42 seconden.quote:Op vrijdag 3 maart 2006 19:28 schreef Swetsenegger het volgende:
Het gadverdamme ik haat een frontpage waarop 20 queries gedraaid worden. Ik vond SuperRembo's oplossing juist zo'n geile query
Maar hij zag er wel heel cool uit en LIJKT veel sneller dan 20 queriesquote:Op vrijdag 3 maart 2006 21:18 schreef SuperRembo het volgende:
[..]
Ik moet toe geven dat het stiekum toch een draak van een query is. Ik heb ff een testje gedraaid met een tabel met 10000 rows... daarmee legde MySQL m'n pc 16 minuten plat. MSSQL deed het met dezelfde data in 42 seconden.
En wat geeft de EXPLAIN van die query? Dat levert meestal wel info waarmee je kunt kijken wat er lang duurt.quote:Op vrijdag 3 maart 2006 11:13 schreef Swetsenegger het volgende:
[..]
De Query?
[ code verwijderd ]
-edit-
indices op a.ad_id (PK), a.genre, g.genre_id (PK)
Of ik begrijp dat explain gewoon niet, of ik doe wat fout.quote:Op vrijdag 3 maart 2006 21:34 schreef Light het volgende:
[..]
En wat geeft de EXPLAIN van die query? Dat levert meestal wel info waarmee je kunt kijken wat er lang duurt.
1 2 3 4 | g ALL PRIMARY NULL NULL NULL 19 Using temporary; Using filesort a ref PRIMARY,genre genre 4 g.genre_id 24 Using where a2 ref PRIMARY,genre genre 4 g.genre_id 24 Using where |
Hij is lastigquote:Op vrijdag 3 maart 2006 21:57 schreef Swetsenegger het volgende:
[..]
Of ik begrijp dat explain gewoon niet, of ik doe wat fout.
Anyway, dit komt eruit
[ code verwijderd ]
quote:Op zaterdag 4 maart 2006 10:49 schreef Light het volgende:
[..]
Hij is lastig
Maar als je nou de key genre in de tabel ad eens aanpast er daar ad_id als tweede index bij zet, wordt het dan sneller?
MySQL heeft de leuke eigenschap dat het maar 1 key (index dus) kan gebruiken.
Forum Opties | |
---|---|
Forumhop: | |
Hop naar: |