Ik heb het volgende probleem.

Twee tabellen.
Personen tabel (25000 records)
persid (Primary key)
voornaam
tussenvoegsel
achternaam (index)

Opstellingen tabel (370000 records)
Opstelkey (Primary key)
wid
Persid
volgorde
gesp
gesc

SELECT sum(o.gesc) as totgescoord,p.achternaam FROM opstelere1 o,personen1 p
where o.persid=p.persid
group by o.persid

Resultaat bovenstaande Query 6809 totaal, Query duurde 0,0176 seconden

Voeg ik echter een Order By toe dan wordt de Query echt een stuk trager.
SELECT sum(o.gesc) as totgescoord,p.achternaam FROM opstelere1 o,personen1 p
where o.persid=p.persid
group by o.persid
order by totgescoord desc

Resultaat Query 6809 totaal, Query duurde 2,7740 seconden

Query alleen op de Opstellingen tabel met het persid
SELECT o.persid,sum(o.gesc) as totgescoord FROM opstelere1 o

group by o.persid
order by totgescoord desc

Resultaat 6809 totaal, Query duurde 0,1732 seconden
Maar ja, het is wel leuk om er een naam bij te hebben ;-)


Ik heb aardig wat gezocht op internet, maar ik kan de oplossing niet vinden.
Enige wat ik zie is dat het probleem zich vaker voordoet na het toevoegen van een sort, maar de oplossing?!?!
Dat is een flinke performance-boost :-)
Een index toevoegen maakt een query niet per definitie sneller, het is alleen zinvol als je hoogstens zo'n 15% van de data ophaalt, anders is er ook een kans dat een index de query trager maakt.

De query is nog wat traag, dat zal komen door de ORDER BY, die moet in de tussentabel (het resultaat van de binnenste query) 25000 rijen sorteren zonder index. Je kunt het verschil meteen zien door de ORDER BY weg te laten, ik gok dat de de query dan een factor 10 sneller zal zijn.
Ad Fundum op 10/03/2021 10:55:42

Een index toevoegen maakt een query niet per definitie sneller, het is alleen zinvol als je hoogstens zo'n 15% van de data ophaalt, anders is er ook een kans dat een index de query trager maakt.

De query is nog wat traag, dat zal komen door de ORDER BY, die moet in de tussentabel (het resultaat van de binnenste query) 25000 rijen sorteren zonder index. Je kunt het verschil meteen zien door de ORDER BY weg te laten, ik gok dat de de query dan een factor 10 sneller zal zijn.

Met of zonder ORDER BY maakt nauwelijks verschil.

Dan moet I/O de bottleneck zijn.

Wat soms helpt is om de tabel opnieuw aan te maken via kopiëren met SQL. Na veel mutaties blijft de nodige lucht in de tabel hangen. Zo worden rijenintern niet daadwerkelijk gewist, alleen gemarkeerd als gewist om de snelheid er in te houden. PostgreSQL stofzuigt de tabellen automatisch, je zou eens kunnen kijken of dat voor de database die jij gebruikt ook bestaat.

Een ander ding om te controleren is of de storage engine niet efficiënter kan zijn. In MySQL / MariaDB kan je misschien experimenteren met andere engines als MyISAM?

Als niets helpt zou je toch eens moeten gaan kijken naar het opschalen van de (eventueel virtuele) hardware.
Ik denk dat Ad Fundum gelijk heeft in het opschalen van de hardware, of iig de toegewezen hoeveelheid geheugen voor MySQL.
Als ik die EXPLAIN bekijk staat er dat gebruik word gemaakt van filesort, dat is een vrij langzame methode.

Waardoor dit komt is ietwat ingewikkeld maar het komt er op neer dat het resultaat niet in het beschikbare geheugen past en in een tijdelijke tabel word geplaatst. Aan het einde van de query worden deze tijdelijke tabellen via een merge-sort gecombineerd en teruggegeven. (meer info hier: https://www.percona.com/blog/2009/03/05/what-does-using-filesort-mean-in-mysql/ en hier: https://petrunia.net/2007/08/29/how-mysql-executes-order-by/).

Opschalen van beschikbaar geheugen voor de InnoDB engine zou dat probleem moeten oplossen, het beperken van de resultaatgrootte ook.
Als laatste, maar dat is iets wat je moet testen m.b.v. profiling, kun je de query opknippen in meerdere queries met kleinere resultsets (aan de PHP kant) en ze daar combineren. Minder mooi maar dat kan in sommige gevallen efficiënter zijn.

Reageren