[PHP] [MySQL] Performanceprobleem?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
Ik ben webmaster van de website van mijn school, waar op de website een ledensysteem is (voor leerlingen), een forum, een chatbox, noem maar op.
Alles is custom-made, wat verschillende voordelen, maar ook nadelen biedt.

Een van de nadelen is het forum:
Bij ieder bericht worden de postcount en gegevens van de poster opnieuw opgezocht.
De gebruikers kunnen zelf het aantal berichten dat per pagina wordt weergegeven aanpassen, hoe meer berichten, hoe meer queries, en hoe langer het duurt voordat een pagina is ingeladen.

Ikzelf heb de limiet ingesteld op 20/pagina, wanneer ik die pagina laat debuggen (daarvoor is een optie), kom ik uit op 68 queries.
Volgens mij kan ik hier flink in snijden, de vraag is hoe ik dat het beste kan doen.
Met een SQL-opdracht worden de berichten en uid's opgehaald, en vervolgens per bericht met twee queries de postcount en of er al een klacht (in de vorm van een pushmessage) over het bericht is gestuurd.

Dit is bij een kleine pagina wel te doen, maar bij een topic met 20 posts erin, duurt het laden bijna 3 seconden. Dat is te lang, denk ik zo.
Ik zoek het probleem in de SQL-queries, die zijn soms nogal uitgebreid.

Zijn er Tweakers die mij een goede oplossing kunnen bieden voor dit probleem?
Ik wil best stukjes code posten, wanneer het nodig is.

We are shaping the future


Acties:
  • 0 Henk 'm!

  • Tux
  • Registratie: Augustus 2001
  • Laatst online: 21:12

Tux

De postcount enzo opslaan in een extra veld in de user tabel, en de user tabel joinen bij de query om de berichten op te halen.

Bij het script om een bericht toe te voegen voeg je een aantal queries toe die de postcount in het profiel, de postcount van het topic en de postcount van het forum updaten.

Dit soort informatie kan je dus beter 'statisch' in de database opslaan om de snelheid te verbeteren.

The NS has launched a new space transportation service, using German trains which were upgraded into spaceships.


Acties:
  • 0 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
En wanneer er een forum totaal geleegd wordt, of een topic getrashed, dan per post bij de user er eentje aftrekken...
Dit is de query om de berichten op te halen:
SQL:
1
SELECT b.bid AS bid, b.datum AS datum, b.content AS content, b.uid AS uid, g.klas AS klas, g.status AS status, g.type AS type, g.naam AS naam, g.signature AS signature, g.openbaarprofiel AS openbaarprofiel, g.ondertitel AS ondertitel, g.lastactivity AS lastactivity FROM fberichten AS b, g_gebruikers AS g WHERE b.tid = '79331' AND g.uid = b.uid ORDER BY bid ASC LIMIT 0, 20

We are shaping the future


Acties:
  • 0 Henk 'm!

  • Tux
  • Registratie: Augustus 2001
  • Laatst online: 21:12

Tux

code:
1
fberichten AS b

Is niet nodig, je kan ook gewoon:
code:
1
fberichten b

doen.

En heb je wel goede indexes ingesteld op de verschillende tabellen?

The NS has launched a new space transportation service, using German trains which were upgraded into spaceships.


Acties:
  • 0 Henk 'm!

  • Hans1990
  • Registratie: Maart 2004
  • Niet online
Dus als ik het goed begrijp zet je eigenlijk een query in een while loop van al je berichten om post count e.d. op te halen ?

Ik zal zeggen: Kijk even in de FAQ van GoT. Zie hier joins: P&W FAQ - SQL

[ Voor 32% gewijzigd door Hans1990 op 03-02-2005 21:15 ]


Acties:
  • 0 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
Ik heb niet alles zelf opgebouwd, ik heb het baantje overgenomen van een (inmiddels ex-)leerling.
Die caps zijn voor zover ik weet voor het overzicht, ik vind het geen slechte gewoonte.

Wat voor indexes wil je weten?

We are shaping the future


Acties:
  • 0 Henk 'm!

  • Tux
  • Registratie: Augustus 2001
  • Laatst online: 21:12

Tux

Alex schreef op donderdag 03 februari 2005 @ 21:15:
Ik heb niet alles zelf opgebouwd, ik heb het baantje overgenomen van een (inmiddels ex-)leerling.
Die caps zijn voor zover ik weet voor het overzicht, ik vind het geen slechte gewoonte.

Wat voor indexes wil je weten?
Heb je keys ingesteld op de velden die je in where clauses enzo met elkaar vergelijkt? Dat kan namelijk heel veel schelen in de performance.

The NS has launched a new space transportation service, using German trains which were upgraded into spaceships.


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
Het is niet een idee om een bestaand systeem te gaan gebruiken wat wel optimaal werkt en dit vervolgens aan te passen aan je eigen wensen? Als ik hoor dat je zo'n 68 queries nodig hebt voor een forumpagina ga ik me toch een beetje afvragen hoe de rest in elkaar zit namelijk. Het is natuurlijk wel eenmalig veel werk maar daarna werk je wel op basis van een product wat ook door anderen verder ontwikkeld wordt.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Tux schreef op donderdag 03 februari 2005 @ 21:14:
code:
1
fberichten AS b

Is niet nodig, je kan ook gewoon:
code:
1
fberichten b

doen.
offtopic:
Maakt dat enig functioneel verschil dan? :?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Tux
  • Registratie: Augustus 2001
  • Laatst online: 21:12

Tux

-NMe- schreef op donderdag 03 februari 2005 @ 21:22:
[...]

offtopic:
Maakt dat enig functioneel verschil dan? :?
Waarschijnlijk niet, maar ik vind het zonder AS mooier staan ;)

The NS has launched a new space transportation service, using German trains which were upgraded into spaceships.


Acties:
  • 0 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
djluc schreef op donderdag 03 februari 2005 @ 21:22:
Het is niet een idee om een bestaand systeem te gaan gebruiken wat wel optimaal werkt en dit vervolgens aan te passen aan je eigen wensen? Als ik hoor dat je zo'n 68 queries nodig hebt voor een forumpagina ga ik me toch een beetje afvragen hoe de rest in elkaar zit namelijk. Het is natuurlijk wel eenmalig veel werk maar daarna werk je wel op basis van een product wat ook door anderen verder ontwikkeld wordt.
Dat gaat veel problemen met zich meebrengen, om te migreren. Ten eerste moet er een (betaalbaar) stabiel systeem gevonden worden (bijvoorbeeld React of vBulletin), dan moeten er veel zaken worden aangepast/toegevoegd, zo worden er nu Oud-Leerlingen, Leerlingen, Docenten en Overige gebruikers geregistreerd. Verder is het niet alleen een forum, maar een compleet CMS, met verschillende onderwerpen en pagina's. Docenten kunnen via die website e-mails sturen, en nog meer dingen.
Dan moeten alle gegevens gemigreerd worden. Ook lekker veel werk...

Nee, een bestaand systeem aanpassen is niet echt handig...

Edit:
Dit is de stuctuur van de tabel fberichten:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
CREATE TABLE `fberichten_old` (
  `bid` int(5) NOT NULL auto_increment,
  `tid` int(5) NOT NULL default '0',
  `content` text NOT NULL,
  `datum` int(20) NOT NULL default '0',
  `uid` int(4) NOT NULL default '0',
  PRIMARY KEY  (`bid`),
  FULLTEXT KEY `content` (`content`),
  KEY `datum` (`datum`),
  KEY `uid` (`uid`),
  KEY `tid` (`tid`)
) TYPE=MyISAM;

[ Voor 23% gewijzigd door Alex) op 03-02-2005 21:32 ]

We are shaping the future


Acties:
  • 0 Henk 'm!

  • hennink
  • Registratie: Augustus 2000
  • Laatst online: 21:33
Doe eens wat query's die je doet direct in je mysql client(bijvoorbeeld phpmyadmin) en zet er EXPLAIN voor.
Kijk hoeveel rows doorlopen worden en welke keys hij gebruikt.
Als je ziet dat hij geen key gebruikt maar je doet wel een WHERE veld1=value maak dan een index aan voor veld1.
ALTER TABLE `tablename` ADD INDEX ( `veld1` )
Doorloop zo al je query's en kijk hoeveel je kan optimaliseren.
Want 3 seconden om al je query's te doen lijkt verdacht veel op het ontbreken van indexen.

alles wat aan kan, gaat kapot. De vraag is alleen wanneer.


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:04
Tux schreef op donderdag 03 februari 2005 @ 21:14:
code:
1
fberichten AS b

Is niet nodig, je kan ook gewoon:
code:
1
fberichten b
Offtopic:
het is niet omdat het niet nodig is, dat je het daarom niet mag doen. Dat zijn gewoon voorkeuren, en het biedt geen enkel voordeel om die AS weg te laten.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:04
Alex schreef op donderdag 03 februari 2005 @ 21:08:

Ikzelf heb de limiet ingesteld op 20/pagina, wanneer ik die pagina laat debuggen (daarvoor is een optie), kom ik uit op 68 queries.
Volgens mij kan ik hier flink in snijden, de vraag is hoe ik dat het beste kan doen.
Met een SQL-opdracht worden de berichten en uid's opgehaald, en vervolgens per bericht met twee queries de postcount en of er al een klacht (in de vorm van een pushmessage) over het bericht is gestuurd.
Kan je dat niet in één keer doen ?
Als er een topic geopend wordt, alle berichten, users die eraan gelinked zijn en evt pushmessages ophalen ?
code:
1
2
3
4
select user.name, user.postcount, bericht.inhoud
from user, bericht
where bericht.userid = user.userid
and bericht.topic_id = <geopende_topic_id>

[ Voor 19% gewijzigd door whoami op 04-02-2005 09:42 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Alex schreef op donderdag 03 februari 2005 @ 21:12:
En wanneer er een forum totaal geleegd wordt, of een topic getrashed, dan per post bij de user er eentje aftrekken...
Je zou er ook voor kunnen kiezen om dit gewoon niet te doen. De user heeft immers de post wel gedaan, alleen is hij niet meer zichtbaar.

Mocht je dit toch willen doen, dan zie ik geen probleem. De acties die je noemt zijn zo zeldzaam dat performance geen primair doel is. Daarnaast is dit volgens mij te doen in 1 query. Hoe je dat doet ligt natuurlijk aan je database opzet.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
Ik heb nu geen kans om de tables te laten analyseren, vanavond wel.
Postcount kan inderdaad bij de user erbij in de tabel, en of er een klacht is verzonden ook. (Dan los ik meteen een ander probleem op).

Als MySQL-client gebruik ik trouwens MySQL-Front.


Dit krijg ik als resultaat als ik EXPLAIN voor de hierbovengenoemde query zet:
tabletypepossible_keyskeykey_lenrefrowsExtra
brefuid,tidtid4const92where used; Using filesort
geq_refPRIMARYPRIMARY4b.uid1

[ Voor 58% gewijzigd door Alex) op 05-02-2005 00:37 ]

We are shaping the future


Acties:
  • 0 Henk 'm!

  • seamus21
  • Registratie: December 2001
  • Laatst online: 24-02-2018
Tips voor wat minder overhead. Ik zeg niet dat je dit misschien niet al gedaan had maar haal er je voordeel uit:

- Normaliseer je database
- Ga na welke queries het meeste worden uitgevoerd en welke tabellen hierbij zijn betrokken. Indexeer deze.
- Dingen die je echt vaak (berekenend) zal gaan ophalen, zoals je zelf al aangeeft bijvoorbeeld postcount, kan je beter in een apart veld opslaan. Ook als dit betekent dat je dan theoretisch redundant bezig bent. Dit scheelt weer 68 select, join, de1337 enzo :) queries.
- Zorg eventueel voor triggers en storedprocs oid (mysql 5++).. Dit zou sneller kunnen werken aangezien dit dichter op db staat.
- Koop een UBER 1337 bak om je spullen te hosten :) :)

[ Voor 6% gewijzigd door seamus21 op 05-02-2005 00:57 ]

Always shoot for the moon. Even if you miss you will land among the stars...


Acties:
  • 0 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
Die laatste tip wordt het lastigste, het is namelijk van een schoolsite, en ja... budget, er is dit jaar al een nieuwe netwerkserver geplaatst.
Wat bedoel je met normaliseer je db? En triggers en Storedprocs? (Ik ben geen MySQL-goeroe)

We are shaping the future


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 20:38

alienfruit

the alien you never expected


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:04
Alex schreef op zaterdag 05 februari 2005 @ 01:33:
Die laatste tip wordt het lastigste, het is namelijk van een schoolsite, en ja... budget, er is dit jaar al een nieuwe netwerkserver geplaatst.
Wat bedoel je met normaliseer je db? En triggers en Storedprocs? (Ik ben geen MySQL-goeroe)
Een goed genormaliseerde DB (een goed , correct datamodel), daar valt het meeste snelheidswinst mee te halen.
Als je DB model niet goed is, zal het lastig zijn om correcte, performante queries te schrijven.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Speedener
  • Registratie: September 2000
  • Laatst online: 18-09 12:54
68 querys :o

OK het is niet netjes om data meerdere keren in een database te zetten, maar als je er 68 querys voor nodig heb om aan die data te komen, en het kan ook makkelijker/sneller zou ik dat toch maar eens gaan overwegen.

En hoevaak wordt nou een heel subforum getrashed?

Maar het zou er wel op neerkomen dat je de DB structuur wat moet gaan veranderen. Als je het gewoon stapje bij beetje doet. Waarschijnlijk in de users table enkele cols erbij (postcount enzo) dan zal het al een stuk beter gaan.

LG Therma V Split WP: HU143MA.U33-HN1636M NK5


Acties:
  • 0 Henk 'm!

  • seamus21
  • Registratie: December 2001
  • Laatst online: 24-02-2018
Alex schreef op zaterdag 05 februari 2005 @ 01:33:
Die laatste tip wordt het lastigste, het is namelijk van een schoolsite, en ja... budget, er is dit jaar al een nieuwe netwerkserver geplaatst.
Wat bedoel je met normaliseer je db? En triggers en Storedprocs? (Ik ben geen MySQL-goeroe)
Normaliseren is simpel gezegd je db zo min mogelijk redundant krijgen. Probeer dit ongeveer tot de 3e vorm te doen. Kijk hier maar eens:

http://www.phphulp.nl/php/tutorials/3/150/259/

Triggers en storedprocs is niet specifiek iets van MySQL sterker nog MySQL ondersteunt het pas sinds kort. Triggers --> MySQL 5.0 en Stored procs MySQL 5.1

Stored proc: Een verzameling SQL statements die op de server staan. Deze kan je dan net zoals een functie aanroepen.

Triggers: Code die na een bepaalde dba ctie uitgevoerd kunnen worden. Bijvoorbeeld voor/na een INSERT.

[ Voor 5% gewijzigd door seamus21 op 06-02-2005 15:25 ]

Always shoot for the moon. Even if you miss you will land among the stars...

Pagina: 1