De titel is misschien niet helemaal duidelijk, ik weet ook niet goed hoe ik het anders in het kort moet duiden.
In ieder geval ik ben bezig met een project wat al enige jaren bestaat. Nu worden er aanpassingen gedaan, deze niet door mij, waarbij een calcutie 3 uur+ duurt wat natuurlijk onacceptabel is.
Er komen dan ook klachten van de gebruikers, wat begrijpelijk is natuurlijk.
Nu ben ik er ingedoken vooral door te te googlen.
Wat ik gedaan heb is een tabel:
- slow_log
- general_log
aangemaakt.
Vervolgens de volgende variabelen ingesteld:
# Variable_name, Value
'general_log', 'ON'
'log_output', 'TABLE'
'log_queries_not_using_indexes', 'ON'
'log_slow_admin_statements', 'OFF'
'log_throttle_queries_not_using_indexes', '0'
'long_query_time', '10.000000'
'min_examined_row_limit', '0'
'slow_query_log', 'ON'
'slow_query_log_file', 'TABLE'
Er draait verder niets op de server enkel dit rapport.
1. aantal records in de slow_log tabel:
Het eerste waar ik van schrik is dat er ruim 6800 records worden weggeschreven in de 'slow_log' tabel.
Dat betekent volgens mij dat er vanuit PHP ruim 6800 keer een query afgevuurd wordt! Waarbij ook heel vaak dezelfde query weer wordt aangeroepen.
Mijn eerste reactie: "Geen wonder dat dit 3 uur duurt, dat is veel te veel!!!" Maar is mijn conclusie gerechtvaardigd?
(Ik heb geen relevante ervaring hiermee en ook geen referentie kader. Ik zelf probeer altijd zo min mogelijk database access uit te voeren.)
2. max query time - indexen:
The max. query_time 00:00:14.91xxx, 5 met 12.xxx, 3 met 11.xxx en 5 met 10.xxx seconden.
Aangezien er geen queries zijn die 30min. duren of langer en dat er dan zo veel records weggeschreven worden, heeft dan te maken dat er geen indexen op de tabellen zitten of niet zodanig dat ze gebruikt worden in de queries.
dit concludeer ik op basis van dat de 'long_query_time' op 10 staat, wat volgens mij wil zeggen 10 sec. Er worden ruim 6800 records weggeschreven. Dit komt volgen mij doordat ik de 'log_queries_not_using_indexes' = ON staat, anders zouden er maar 14 records in de slow_log tabel weggeschreven worden.
Nu ben ik geen database expert maar ik heb via de slow_log queries bekeken via de sql_text. En heb ik bv. als er een query was die op datum zoekt in de where clause, een index op datum gezet. Even zo als er een where clause was die op WHERE datum =... AND jur = ... AND bu =... AND scenario = ... zocht, heb ik deze in een index gezet.
Echter dit brengt niets. Er worden nog bijna net zoveel records weggeschreven! En het duurt nog net zo lang.
3. wegschrijven van records
Daarnaast worden er ook veel records weggeschreven nadat er berekeningen zijn uitgevoerd. Telkens in sets van 500 volgens mij.
Nu weet ik op dit moment niet of in de code zo gedaan is of dat MySQL ze zelf ophakt in sets van 500.
Wat ik wel vreemd vindt, althans wat ik in de slow_log terug vindt is de syntax:
SELECT table (veld1, veld2,...)
INSERT INTO tabel (veld1, veld2,...)
SELECT '20170630', waarde1',' waarde2',...
UNION ALL SELECT '20170630', waarde1',' waarde2',...
UNION ALL SELECT '20170630', waarde1',' waarde2',...
UNION ALL SELECT '20170630', waarde1',' waarde2',...
Maakt MySQL dit zelf zo aan (in zijn execution_plan), UNION ALL heb ik nooit gezien zeker niet op deze manier voor INSERT INTO? (Eerlijk gezegd dit kan ook aan mij liggen)
4. Wat kan ik nog meer analyseren?
- Nu zit ik met: hoe nu verder? Mag ik de conclussie al maken "Dit moet herschreven worden"? Want 6800 keer een database access, dat gaat niet veel korter worden.
- Of is mijn analyse met de slow_log niet helemaal objectief, ik bedoel doe ik nog iets niet goed? Moet ik nog meer bekijken? moet ik nog meer analyseren?
- Of moet/kan ik met betere indexen nog veel tijdwinst halen en dan niet 30 min maar ruim 2,5 uur of meer?
Nico