Last night at the MySQL NY Meetup we continued on from a very successful July presentation on “Practical Performance Tips & Tricks”. I must admit after speaking and standing all day for the MySQL DBA Bootcamp for the Oracle DBA it was a stretch, and we didn’t cover all material as expected, but the evening was still very productive to everybody. Links are here for my August Presentation and July Presentation.
Thanks to Marc and the team from LogicWorks for again sponsoring our NY Meetup Event. We don’t get the beer and food any other way.
As a consultant working on client sites even in the time from the previous meeting, I see a number of simple steps that can be applied to every single MySQL environment and last nights talk placed some focus on this. The following is the homework that has been set for attendees, so next month we can have a panel discussion and then continue more on the analysis of MySQL.
This homework focuses on three areas. It seems a lot, but it will be worth it.
- Collection of SQL statements (in various forms)
- Monitoring of raw MySQL Status information
- Review of Schema Data Types for more optimal storage
This information is to be collected.
- Production is to have slow query log enabled and long_query_time =1
- Daily review of Production slow query log to view the longest running and most frequent (Slide Aug-13)
- All development and test environments have general log and slow query log enabled.
- All application paths to be tested in development or testing, to capture all SQL. Use self documenting approach (Slide: Aug-21)
Your outputs will include offending SQL statements via the Slow Query log that require investigation, extra credit for doing an EXPLAIN and a SHOW CREATE TABLE for each table in the query for analysis of improving the queries.
You will have a review of every SQL statement. A simple desk check will determine are there any queries which are exact duplicates, are there any queries that could be combined (as they use the same where condition). Are there any queries that are repeated a lot, but with only changing values. These are a clear candidate for combining into a single query.
MySQL Status Information
The MySQL Status can provide help into where to look for problems. This is the raw fundamentals that either home grown scripts or MySQL Network Monitoring and Advisory Service use to provide monitoring of important information (e.g. Buffer Hit Ratio) and can provide alerts of present or potential pending problems. We will not be reviewing all these status (~250) or developing any detailed analysis, however this is designed to show you the building blocks.
You should collect figures for 1 minute, 1 hour and 1 day that represent appropriate load on your system.
$ mysqladmin -uroot -p -r -i 1 -c 60 extended-status | grep -v " | 0 " > minute.log
$ mysqladmin -uroot -p -i 60 -c 60 extended-status > hourly.log
$ mysqladmin -uroot -p -i 3600 -c 24 extended-status > daily.log
Extra credit for downloading Statpack and doing an analysis of the statistics. The trick is to take the first and last status output from each of the Hourly and Daily logs to get a 1 hour picture and a 1 day picture.
For reviewing the schema, try to use a static production sized copy (e.g. a copy of production in a test environment). This ensures you don’t make changes that will cause your production system to fail, and before and after figures are for the same data set as it’s not changing during production use.
- Calculate size of present data
- Review schema for immediate size improvements (Slide Jul-59)
- Apply size improvements and re-run to see size improvements.
Calculate Size of all schemas
select table_schema, count(*) as tables, sum(data_length+index_length)/1024/1024 as total_mb, sum(data_length)/1024/1024 as data_mb, sum(index_length)/1024/1024 as index_mb from information_schema.tables group by table_schema order by 3 desc;
Calculate Size of all tables for given schema
use test; select table_name,engine,row_format,avg_row_length,table_rows, (data_length+index_length)/1024/1024 as total_mb, (data_length)/1024/1024 as data_mb, (index_length)/1024/1024 as index_mb from information_schema.tables where table_schema=database() order by 6 desc;