Lage kardinaliteit

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
Ik heb een probleem. Ik ben een interne prijsvergelijker voor een grote webwinkel aan het maken, zodat we snel kunnen zien of we goedkoop genoeg zijn :p Het overzicht wordt gesorteerd op polulariteit, dus het product dat het meest verkocht is bovenaan. Hiervoor speelt de volgende query een belangrijke rol:
SQL:
1
2
3
4
5
6
7
8
9
SELECT p.products_id, p.products_ordered, p.prijs as onze_prijs, a.adviesprijs as adviesprijs, c1.prijs as c1_prijs, c2.prijs as c2_prijs
FROM products p
LEFT JOIN adviesprijzen a ON a.EANcode = p.EANcode
LEFT JOIN feed_concurrenten c1 ON p.EANcode = c1.EAN AND c1.naam = 'concurrent1.nl'
LEFT JOIN feed_concurrenten c2 ON p.EANcode = c2.EAN AND c2.naam = 'concurrent2.nl'
WHERE p.EANcode != ''
AND p.products_status = 1
GROUP BY p.products_id
ORDER BY p.products_ordered DESC, p.products_id ASC
Dit duurt 0,8s op mijn lokale dev-machine. Zonder GROUP BY nog 0,10s tot 0,15s. Dat is al een groot verschil, maar het is nog te langzaam. En als ik dit niet doe verschijnen sommige producten bij een van onze concurrenten dubbel. Zij hebben ergens de verkeerde ean-codes ingevuld...

Als ik de GROUP BY laat staan, maar de ORDER BY zo verander dat er alleen op products_id wordt gesorteerd duurt de query nog maar 0,02s tot 0,05s. Dat is de snelheid die ik zoek! Maar dan staan ze in min-of-maar willekeurige volgorde.

Er zijn indexes op alle relevante kolommen, maar de index op products_ordered lijkt geen invloed te hebben. De query wordt niet sneller of langzamer als ik de key verwijder of opnieuw aanmaak.

De products tabel bestaat uit ruim 17.000 producten, maar er zijn maar 144 verschillende waardes voor products_ordered. De kardinaliteit is dus slechts een honderdste van de hele tabel, en nog stecht verdeeld ook. Veel producten zijn niet of maar een paar keer gekocht. Dat maakt de index vrijwel waardeloos.

Kan ik hier iets aan doen, of moet ik er gewoon meer hardware tegenaan smijten?
Of gewoon mensen meer laten kopen zodat de kardinaliteit vanzelf beter wordt :D

Acties:
  • 0 Henk 'm!

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Het belangrijkste wat je eerst moet oplossing is de fout die MySQL je laat maken. Je groepeert nu op p.products_id terwijl de overige velden niet in een aggregate functie zitten. Je krijgt dus een willekeurige prijs van de verschillende voorkomende product_id's en dat is denk ik niet wat je wilt.

Zie: Programming FAQ - SQL

Oops! Google Chrome could not find www.rijks%20museum.nl


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
@P_de_B
Waar c1 of c2 meerdere verschillende prijzen voor dezelfde eancode heeft staan kan ik sowiezo weinig met de data, want ik heb geen idee welk product overeenkomt met die van ons. Dus beter dan "willekeurig" is dan niet echt mogelijk.

@RobIII
Sorry, ik dacht dat dit hier beter thuishoorde.
Edit: bedankt voor het verplaatsen, ik had nieteens door dat je em al verplaatst had ;)

[ Voor 12% gewijzigd door Peetz0r op 05-05-2011 15:39 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
P.E.T.E.R. schreef op donderdag 05 mei 2011 @ 15:37:
@P_de_B
Waar c1 of c2 meerdere verschillende prijzen voor dezelfde eancode heeft staan kan ik sowiezo weinig met de data, want ik heb geen idee welk product overeenkomt met die van ons. Dus beter dan "willekeurig" is dan niet echt mogelijk.
P_de_B doelt hier op: Hoe werkt dat GROUP BY nu eigenlijk?
MySQL is een hele brakke database, die deze laatste constructie wel toestaat. En volgens de handleiding is het 'by design' dat je vervolgens random waardes in kolom B aantreft. Don't do it.

[ Voor 16% gewijzigd door RobIII op 05-05-2011 15:39 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 04-07 11:10
Ik krijg ook het idee dat je database niet helemaal schoon is als ik dit zo lees. Als je er toch niets mee kan als een product vaker voorkomt bij 1 concurrent, waarom sta je het dan toe? Zet er dan een constraint op, dan gebeurt het ook niet. Daarna kun je meteen je hele GROUP BY achterwege laten want die doet dan niets meer.

Waarom kies je trouwens voor een LEFT JOIN? in het geval het product niet voorkomt bij de conncurrent of je niet over de codes beschikt dan kun je het toch net zo goed skippen?

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 13:10
P.E.T.E.R.: als EANcodes niet uniek zijn (wat me juist wel het idee erachter lijkt, maar goed) dan kun misschien nog steeds beter het minimum en maximum weergeven zodat je in ieder geval als gebruiker kunt zien dat de prijs niet exact klopt. Je kunt dat met de GROUP BY-clause doen, maar je kunt die ten behoeve van de performance ook weglaten en de resultaten in de applicatiecode (PHP of iets dergelijks?) samenvoegen of markeren als dubbelen; dit is een goede optie als die dubbele resultaten zeldzaam zijn.

Tenslotte kun je nog proberen een index te maken op (products_ordered DESC, products_id ASC) want dat is tenslotte waar je op sorteert.

@Johnny: ik kan me voorstellen dat je een resultaat wel wil zien als een product wél bij de ene maar niet bij de andere shop te krijgen is. Met een gewone join krijg je alleen resultaten als alle vier de prijzen bekend zijn.

[ Voor 14% gewijzigd door Soultaker op 05-05-2011 15:43 ]


Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
MySQL is een hele brakke database, die deze laatste constructie wel toestaat. En volgens de handleiding is het 'by design' dat je vervolgens random waardes in kolom B aantreft. Don't do it.
Sja, de site bestaat al een paar jaar en draait prima. Ik werk hier net twee maanden, en ik ben niet van plan om het hele ding eventjes te herschrijven...

@.Johnny, @Soultaker
Sja, de bron van de data is best smerig. Niks aan te doen. eancodes zijn bij ons en onze leverancier uniek (of afwezig...) maar vooral c2 maakt er een zooitje van. Kan ik niets aan doen. Ik kan wel alle dubbele eruit gooien, maar ja... Ik zal kijken wat een index op (products_ordered DESC, products_id ASC) doet, maar ik denk niet zoveel.

Acties:
  • 0 Henk 'm!

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 04-07 11:10
Qua LEFT/RIGHT/INNER/OUTER: geldt dat nog steeds als ook de hele adviesprijs mist? kan natuurlijk.

En liever dan je woord ervoor te nemen ben ik wel benieuwd welke keys je hebt; je JOINet op 2 velden, zitten die ook gezellig samen in een key in de juiste volgorde? of heb je losse keys per veld?

Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
De adviesprijs is er altijd, alleen bij c1 oen/of c2 missen er best veel (zij verkopen niet precies hetzelfde als wij). De key op (products_ordered DESC, products_id ASC) helpt totaal niet, verder heb ik inderdaad losse keys per veld op:
products.products_id (PRIMARY)
products.EANcode
products.products_ordered
adviesprijzen.artikelnummer (PRIMARY)
adviesprijzen.EANcode
feed_concurrenten.id (PRIMARY)
feed_concurrenten.EAN

En nog meer op de tabel products

[ Voor 7% gewijzigd door Peetz0r op 05-05-2011 15:57 ]


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 13:10
P.E.T.E.R. schreef op donderdag 05 mei 2011 @ 15:46:
Ik zal kijken wat een index op (products_ordered DESC, products_id ASC) doet, maar ik denk niet zoveel.
Test dan ook zonder de GROUP BY clause, hè!

Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
Soultaker schreef op donderdag 05 mei 2011 @ 15:57:
[...]

Test dan ook zonder de GROUP BY clause, hè!
P.E.T.E.R. schreef op donderdag 05 mei 2011 @ 15:28:
I...Dit duurt 0,8s op mijn lokale dev-machine. Zonder GROUP BY nog 0,10s tot 0,15s....
Dat is niet veranderd

Acties:
  • 0 Henk 'm!

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 04-07 11:10
zou even een key toevoegen op feed_concurrenten(EAN, naam) en feed_concurrenten(naam, EAN).

verder zou ik de key op products uitbreiden met EANcode, dan joined ie sneller je adviesprijzen erbij. En daar zou ik een gewone JOIN van maken ipv LEFT, aangezien je zelf aangeeft dat de adviesprijs er altijd is.

-edit dus: product(products_ordered DESC, products_id ASC, EANcode)

[ Voor 10% gewijzigd door .Johnny op 05-05-2011 16:03 ]


Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
En ook dat maakt weinig verschil, maar ik ga er volgende week verder naar kijken.
Ik werk namelijk niet na bevrijdingsdag of in het weekend

Acties:
  • 0 Henk 'm!

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 04-07 11:10
raar. wat zegt EXPLAIN?

Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
code:
1
2
3
4
5
id  select_type  table   type   possible_keys   key      key_len  ref                     rows    Extra 
1   SIMPLE       p       ALL    EANcode         NULL     NULL     NULL                    17145   Using where; Using temporary; Using filesort
1   SIMPLE       c1      ref    EAN,naam,EAN_2  EAN      257      mijnshop_db.p.EANcode   1    
1   SIMPLE       c2      ref    EAN,naam,EAN_2  EAN      257      mijnshop_db.p.EANcode   1    
1   SIMPLE       u       ref    EANcode         EANcode  66       mijnshop_db.p.EANcode   1       Using where; Using index

Acties:
  • 0 Henk 'm!

  • SPee
  • Registratie: Oktober 2001
  • Laatst online: 11-09 15:48
De products tabel bestaat uit ruim 17.000 producten, maar er zijn maar 144 verschillende waardes voor products_ordered. De kardinaliteit is dus slechts een honderdste van de hele tabel, en nog stecht verdeeld ook. Veel producten zijn niet of maar een paar keer gekocht. Dat maakt de index vrijwel waardeloos.
Het probleem is dat de waardes voor products_ordered meerdere keren voor kunnen komen. Dus als je daar op gaat sorteren, dan moet de database controleren of product 1 waarde X heeft, maar ook product 17.000. Hierdoor moeten eerst de producten worden afgelopen, voordat de sortering kan worden gemaakt. Daar zit die tijd in.


[edit]: Die GROUP BY ervoor helpt ook niet. Als MySQL een random waarde pakt, is het m.i. niet raar dat de DB hier het langst over doet. De Index is dan niet te gebruiken. In veel andere databases zou het een foute query zijn geweest, waar je het sneller zou kunnen zien. Misschien wordt heel de Index op products_ordered niet gebruikt, omdat hij al de Index op product_id gebruikt en niet snel de koppeling tussen deze twee kan oppakken (in deze situatie).

[ Voor 26% gewijzigd door SPee op 05-05-2011 16:47 ]

let the past be the past.


Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
SPee schreef op donderdag 05 mei 2011 @ 16:39:
[...]


Het probleem is dat de waardes voor products_ordered meerdere keren voor kunnen komen. Dus als je daar op gaat sorteren, dan moet de database controleren of product 1 waarde X heeft, maar ook product 17.000. Hierdoor moeten eerst de producten worden afgelopen, voordat de sortering kan worden gemaakt. Daar zit die tijd in.
Maar waarom gebruikt hij niet de index, zodat hij sneller ziet of product 17.000 de waarde wel/niet heeft? Of zie ik nu iets verkeerd?

Zolang dit niet is opgelost kan ik niet genieten van het bevrijdingsfestival...

Acties:
  • 0 Henk 'm!

  • RaZ
  • Registratie: November 2000
  • Niet online

RaZ

Funky Cold Medina

Soultaker schreef op donderdag 05 mei 2011 @ 15:42:
P.E.T.E.R.: als EANcodes niet uniek zijn (wat me juist wel het idee erachter lijkt, maar goed) dan kun misschien nog steeds beter het minimum en maximum weergeven zodat je in ieder geval als gebruiker kunt zien dat de prijs niet exact klopt.

[..]
EAN is altijd uniek. Kan niet anders.. Maar.. Ze zijn dusdanig uniek, dat van 1 product meerdere kleuren zijn, elke kleur z'n eigen EAN heeft.

Dus een product selecteren op basis van de EAN is niet handig.

Even vanuitgaand dat de TS 1 product (ongeacht de kleur) wil checken, en niet 1 series uit 1 productlijn.

Ey!! Macarena \o/


Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
RaZ schreef op donderdag 05 mei 2011 @ 16:50:
[...]

EAN is altijd uniek. Kan niet anders.. Maar.. Ze zijn dusdanig uniek, dat van 1 product meerdere kleuren zijn, elke kleur z'n eigen EAN heeft.

Dus een product selecteren op basis van de EAN is niet handig.

Even vanuitgaand dat de TS 1 product (ongeacht de kleur) wil checken, en niet 1 series uit 1 productlijn.
Onze producten hebben geen meerdere kleuren (en als we die wel hadden stonden ze erin als losse producten). De EANcode is de enige manier om in de data van c1 en c2 o0nze producten terug te vinden. Zij hebben zelf zeker andere product_id's en als ze niet dezelfde leverancier hebben ook andere artikelnummers. En dat laatste kunnen we sowieso niet zien. De EANcodes zijn de enige betrouwbare gegevens die ik heb, en daar zit soms troep tussen...

Acties:
  • 0 Henk 'm!

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 04-07 11:10
Dan snap ik nog steeds niet dat je het "cleanen" elke keer dat de data opgevraagd wordt laat doen. Waarom doe je dat niet @ import? dat is het geeigende moment om je data schoon te maken zodat je het vervolgens elke keer met zekerheid en snel kunt queryen. Je zou dat ook van de query die je hier doet kunnen afvragen; als dit de enige view is die je gebruikt, waarom store je dat dan niet gewoon?

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Voor GROUP BY moet hij sorteren, daarna voor ORDER BY ook. Als hij de ene anders moet sorteren (GROUP BY a,b,c ORDER BY a,b mag wel, GROUP BY a ORDER BY a,b mag ook, maar GROUP BY a,b ORDER BY b,a niet), dan kan hij voor in ieder geval de ORDER BY geen index gebruiken.

Ook werkt een index niet als de sortering verschillend is: de ene kolom ASC, andere DESC.

Ik zou hem zo doen:
SQL:
1
2
3
4
5
6
7
8
9
SELECT p.products_id, p.products_ordered, p.prijs as onze_prijs, a.adviesprijs as adviesprijs, c1.prijs as c1_prijs, c2.prijs as c2_prijs
FROM products p
LEFT JOIN adviesprijzen a ON a.EANcode = p.EANcode
LEFT JOIN feed_concurrenten c1 ON p.EANcode = c1.EAN AND c1.naam = 'concurrent1.nl'
LEFT JOIN feed_concurrenten c2 ON p.EANcode = c2.EAN AND c2.naam = 'concurrent2.nl'
WHERE p.EANcode != ''
AND p.products_status = 1
GROUP BY p.products_ordered,p.products_id
ORDER BY p.products_ordered DESC, p.products_id DESC

En dan een index op producten: (products_status,products_ordered,products_id)
En bij feed_concurrenten een primary key op (EAN, naam)
En bij adviesprijzen een index op (EANcode)
zou even een key toevoegen op feed_concurrenten(EAN, naam) en feed_concurrenten(naam, EAN).
Allebei is niet nodig.
verder zou ik de key op products uitbreiden met EANcode, dan joined ie sneller je adviesprijzen erbij.
Onzin, als je al een covering index wilt maken, dan moeten er nog wel wat extra kolommen bij.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
RaZ schreef op donderdag 05 mei 2011 @ 16:50:
[...]
EAN is altijd uniek. Kan niet anders.. Maar.. Ze zijn dusdanig uniek, dat van 1 product meerdere kleuren zijn, elke kleur z'n eigen EAN heeft.
Let er wel op dat dit het theoretische gedeelte is. Praktijk is veelal ietwat anders.
Maar zelfs in het theoretische geval kan je nog makkelijk in de knoei komen, want EAN is zo uniek dat je per verpakking een andere moet hebben. Oftewel de ene leverancier koopt het per pallet, de andere per doos en de derde per stuk dan kunnen ze 3 verschillende ean-codes hanteren...

Daarnaast heb je nog partijen die bewust een eigen ean-code/sticker hanteren omdat die juist niet in prijsvergelijkers etc willen voorkomen...

EAN is vooral theoretisch een mooi systeem, praktisch is het veelal een baggersysteem door mensen die het fout toepassen...

Acties:
  • 0 Henk 'm!

  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 00:41

The Eagle

I wear my sunglasses at night

@GlowMouse: voor zover ik weet maken aliassen in een ORDER BY niet meer uit. Een ORDER BY wordt op de gehele opgehaalde dataset uitgevoerd, dus dan ga je kijken naar de kolommen die je hebt gebruikt in de select.
Vandaar dat ORDER BY 1,2,3 ook gewoon kan :)
Bij Oracle werkt het iig zo, maar ik kan me niet voorstellen dat MySQL anders zou werken ;)

Gezien het probleem van TS en het feit dat hij continue de zelfde data op wil halen, zou ik zelf eens proberen of ik niks met een inline view kon ipv de joins.
Dat wordt dan iets als onderstaande (meteen even de ORDER BY verduidelijkt en de GROUP aangepast):
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT 
p.products_id, 
p.products_ordered, 
p.prijs as onze_prijs, 
a.adviesprijs as adviesprijs, 
(SELECT MIN(c1.prijs) from feed_concurrenten c1 where p.EANcode = c1.EAN AND c1.naam = 'concurrent1.nl')  as c1_prijs, 
(SELECT MIN(c2.prijs) from feed_concurrenten c2 where p.EANcode = c2.EAN AND c2.naam = 'concurrent1.nl')  as c2_prijs 
FROM products p 
LEFT JOIN adviesprijzen a ON a.EANcode = p.EANcode 
WHERE p.EANcode != '' 
AND p.products_status = 1 
GROUP BY p.products_id, p.products_ordered, p.products_id 
ORDER BY 2 DESC, 3 ASC


Door de inline view te gebruiken kun je tevens zonder veel moeite meteen de minimale prijs van je concurrent pakken, want ik neem aan dat je daarin geinteresseerd bent ;)

[ Voor 10% gewijzigd door The Eagle op 07-05-2011 14:13 ]

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
The Eagle schreef op zaterdag 07 mei 2011 @ 14:09:
@GlowMouse: voor zover ik weet maken aliassen in een ORDER BY niet meer uit. Een ORDER BY wordt op de gehele opgehaalde dataset uitgevoerd, dus dan ga je kijken naar de kolommen die je hebt gebruikt in de select.
Ik heb het niet over aliassen :?

Acties:
  • 0 Henk 'm!

  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 00:41

The Eagle

I wear my sunglasses at night

GlowMouse schreef op zaterdag 07 mei 2011 @ 14:58:
[...]

Ik heb het niet over aliassen :?
Niet? Hoe noem je
ORDER BY p.products_ordered DESC, p.products_id DESC
dan :?

;)

Maar back on topic, benieuwd of TS er al uit is :)

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)


Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
Ik ben eruit!

SQL:
1
2
3
4
5
6
7
8
SELECT p.products_id, p.products_ordered, p.prijs as onze_prijs, a.adviesprijs as adviesprijs, c1.prijs as c1_prijs, c2.prijs as c2_prijs 
FROM products p 
LEFT JOIN adviesprijzen a ON a.EANcode = p.EANcode 
LEFT JOIN feed_concurrenten c1 ON p.EANcode = c1.EAN AND c1.naam = 'concurrent1.nl' 
LEFT JOIN feed_concurrenten c2 ON p.EANcode = c2.EAN AND c2.naam = 'concurrent2.nl' 
WHERE p.EANcode != '' 
AND p.products_status = 1
GROUP BY p.products_ordered DESC, p.products_id ASC
0,8s
SQL:
1
2
3
4
5
6
7
8
SELECT p.products_id, p.products_ordered, p.prijs as onze_prijs, a.adviesprijs as adviesprijs, c1.prijs as c1_prijs, c2.prijs as c2_prijs 
FROM products p 
LEFT JOIN adviesprijzen a ON a.EANcode = p.EANcode 
LEFT JOIN feed_concurrenten c1 ON p.EANcode = c1.EAN AND c1.naam = 'concurrent1.nl' 
LEFT JOIN feed_concurrenten c2 ON p.EANcode = c2.EAN AND c2.naam = 'concurrent2.nl' 
WHERE p.EANcode != '' 
AND p.products_status = 1
GROUP BY p.products_ordered DESC, p.products_id DESC
0,003s

Dat is nou een goed begin van de week!

En dan nu natuurlijk de vraag: hoe kan het dat twee lettertjes mijn query 200 keer zo snel maken? De output van EXPLAIN is bij beide queries hetzelfde als hierboven:
code:
1
2
3
4
5
id  select_type  table   type   possible_keys   key      key_len  ref                     rows    Extra 
1   SIMPLE       p       ALL    EANcode         NULL     NULL     NULL                    17145   Using where; Using temporary; Using filesort
1   SIMPLE       c1      ref    EAN,naam,EAN_2  EAN      257      mijnshop_db.p.EANcode   1
1   SIMPLE       c2      ref    EAN,naam,EAN_2  EAN      257      mijnshop_db.p.EANcode   1
1   SIMPLE       u       ref    EANcode         EANcode  66       mijnshop_db.p.EANcode   1       Using where; Using index

[ Voor 25% gewijzigd door Peetz0r op 09-05-2011 09:21 ]


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
http://dev.mysql.com/doc/...rder-by-optimization.html
Zie 3e puntje: Mysql kan het 2e deel vd index niet gebruiken als je DESC en ASC mixed.

{signature}


Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
Hehwut?!!
Welke index hij gebruikt hangt af van LIMIT enzo... De query wordt ook steeds langzamer als ik de LIMIT verhoog.

De resultaten:
code:
1
2
3
4
5
6
7
8
(0,0014 sec) DESC, DESC LIMIT     0,    10: 1      SIMPLE      p      index    EANcode      products_ordered      8      NULL      10      Using where
(0,8300 sec) DESC,  ASC LIMIT     0,    10: 1      SIMPLE      p      range    EANcode      EANcode             130      NULL   16970      Using where; Using temporary; Using filesort
(0,0800 sec) DESC, DESC LIMIT   400,   410: 1      SIMPLE      p      index    EANcode      products_ordered      8      NULL     818      Using where
(0,8300 sec) DESC,  ASC LIMIT   400,   410: 1      SIMPLE      p      range    EANcode      EANcode             130      NULL   16970      Using where; Using temporary; Using filesort
(0,8300 sec) DESC, DESC LIMIT   500,   510: 1      SIMPLE      p      range    EANcode      EANcode             130      NULL   16970      Using where; Using temporary; Using filesort
(0,8300 sec) DESC,  ASC LIMIT   500,   510: 1      SIMPLE      p      range    EANcode      EANcode             130      NULL   16970      Using where; Using temporary; Using filesort
(0,7500 sec) DESC, DESC LIMIT 17000, 17010: 1      SIMPLE      p      ALL      EANcode      NULL               NULL      NULL   17145      Using where; Using temporary; Using filesort
(0,7500 sec) DESC,  ASC LIMIT 17000, 17010: 1      SIMPLE      p      ALL      EANcode      NULL               NULL      NULL   17145      Using where; Using temporary; Using filesort


Nu wordt ie melemaal mooi:
GROUP BY p.products_ordered DESC, p.products_id DESC LIMIT 443, 453 gaat in 0,06 sec
GROUP BY p.products_ordered DESC, p.products_id DESC LIMIT 444, 454 gaat in 0,83 sec
Hoe kan dit? Als ik meer/minder dan 10 rijen ophaal is dit effect ook weer anders enzo. Raar... Maar de queries voor de eerste paar honderd rijen zijn nu snel :)

[ Voor 10% gewijzigd door Peetz0r op 09-05-2011 09:57 ]


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Lees eens de gerelateerde pagina's bij de gegeven link. ;)

{signature}


Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
Voutloos schreef op maandag 09 mei 2011 @ 09:58:
Lees eens de gerelateerde pagina's bij de gegeven link. ;)
Ik zie daar nog niet de oplossing. Ik heb het nu over de effecten die ik zie bij het gebruik van DESC, DESC en steeds grotere waardes voor LIMIT.

Ik heb my-small.ini vervangen door my-large.ini, en zo o.a. de sort_buffer_size en read_rnd_buffer_size flink vergroot, maar ik zie nog steeds precies hetzelfde effect bij dezelfde waardes.

Als het uitmaakt, dit in een machine met WinXP 32bit, een 2,93GHz Core 2 Duo en 4GB (effectief 3,25...) RAM en een enkele WD schijf over SATA

De live-site draait op Byte clusterhosting en is loeisnel (zelfs de css is sneller dan lokaal, wtf!), maar ik heb geen idee of mijn queries daar iets aan hebben.

[ Voor 10% gewijzigd door Peetz0r op 09-05-2011 10:27 ]


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Gerelateerde pagina's -> goh eentje over 'limit' -> 1e bulletpoint. Ah hehe.

{signature}


Acties:
  • 0 Henk 'm!

  • Peetz0r
  • Registratie: Mei 2009
  • Laatst online: 08-09 22:28
Heh, ook daarzo staan best wel boeiende dingen, maar weinig waar ik iets mee kan.
If you are selecting only a few rows with LIMIT, MySQL uses indexes in some cases when normally it would prefer to do a full table scan.
Soms wel, soms niet. Zou het aan het weer liggen?
If you use LIMIT row_count with ORDER BY, MySQL ends the sorting as soon as it has found the first row_count rows of the sorted result, rather than sorting the entire result. If ordering is done by using an index, this is very fast. If a filesort must be done, all rows that match the query without the LIMIT clause must be selected, and most or all of them must be sorted, before it can be ascertained that the first row_count rows have been found. In either case, after the initial rows have been found, there is no need to sort any remainder of the result set, and MySQL does not do so.
Als er een index gebruikt wordt is het snel. Maar dat is alleen bij volle maan begrijp ik?

Ik heb serieus geen idee waar ik naar moet zoeken, en ik heb niet de keus om 'eventjes' een ander RDBMS te kiezen...
Pagina: 1