Analyze MySQL Performance

Table of Contents

Analyze MySQL Performance
Tuning
Slow queries and Slowlog
Brought to you by Rick James

Analyze MySQL Performance


When asked to analyze the performance of a MySQL server, there are two main tasks (tuning and slowlog) I like to start with. The groundwork for them can be done by the customer.

The deliverables:

    ⚈  Short list of settings (VARIABLES) to change in my.cnf.
    ⚈  Recommendations for speeding up the 'worst' queries.
    ⚈  (possibly) Schema or Architectural recommendations.

In doing these tasks, I get a feel for what the system is doing, thereby jumpstarting any further involvement with the customer's site.

The tuning is usually a one-time task, but may be rerun as the data grows and/or major changes are made to the application.

The Slowlog analysis should be rerun periodically.

Tuning


Please provide

    ⚈  How much RAM in the server
    ⚈  SHOW VARIABLES; -- the tunables
    ⚈  SHOW GLOBAL STATUS; -- various metrics

Please take GLOBAL STATUS after the server has been running at least 24 hours. (Otherwise things like 'cold cache' invalidate some of the findings.)

The SHOWs need to be in machine readable format.

Privacy: There is nothing very sensitive in the SHOWs. However, if you are especially paranoid, you could mask out any ip addresses and host names. Nothing significant will be lost from the analysis.

With those, I will use an automated script compute about 200 formulas and check for reasonable values. Usually about 20 are flagged as 'suspect'. Then I review them the results and clean up things. The bottom line is a few concrete recommendations for

    ⚈  Changing a few variables.
    ⚈  (maybe) Converting away from MyISAM. (I have tips on the task, if you have not yet done such.)
    ⚈  (maybe) Turn off the Query cache. (Perhaps under 5% of Production systems benefit from the QC.)
    ⚈  (probably) Turning on and analyzing the slowlog (below).

If you choose to post online, see a free tool such as
    ⚈  
post.it
    ⚈  pastebin
Caveat: pastebin may get this (for reasons unknown): "This page is no longer available. It has either expired, been removed by its creator, or removed by one of the Pastebin staff."

Slow queries and Slowlog


Setup:

    ⚈  Set long_query_time = 1 -- Preferrable in my.cnf We may change that threshhold up or down later, but this is a reasonable start.
    ⚈  Set up the slowlog to be captured to FILE.
    ⚈  Turn on (the details of this vary with the Version)
    ⚈  Wait at least 24 hours.

Writing slow_log to file -- this is preferred, since there are tools for condensing such:
   log_output = FILE
   slow_query_log = ON
   slow_query_log_file = (fullpath to some file)
   long_query_time = 1
   log_slow_admin_statements = ON
   log_queries_not_using_indexes = OFF

Notes:
    ⚈  log_output can be TABLE to write to mysql.slow_log, or FILE,TABLE to write both
    ⚈  slow_query_log_file has a default; is not needed for TABLE
    ⚈  long_query_time is a float, and can be as low as 0, but that gets verbose; default is a 'useless' 10
    ⚈  admin statements tend to be slow but infrequent
    ⚈  not_using_indexes is mostly clutter; simply worry about those that are slow
    ⚈  If running on a Slave, consider using log_slow_slave_statements

Other options (version dependent; incomplete):
   log_slow_rate_limit=100
   log_slow_rate_type=query
   log_slow_verbosity=full
   slow_query_log_always_write_time=1
   slow_query_log_use_global_control=all
   innodb_monitor_enable=all
   userstat=1

Gather results for me (preferrably using FILE):

    ⚈  Digest the results using either of these:
    `pt-query-digest`  -- from Percona.com
    `mysqldumpslow -s t`
    ⚈  Grab the first few (perhaps 5) queries. They will be sorted by (frequency * avg-time), which is the most useful.
    ⚈  Provide SHOW CREATE TABLE -- for each table
    ⚈  Provide EXPLAIN SELECT ... -- for each query

Analyze Results: Usually (not always), I can then provide a concrete suggestion on speeding up each query:

    ⚈  Add a particular index (often 'composite')
    ⚈  Reformulate the query (a simple case is not hiding an indexed column in a function; more complex involves adding/removing subqueries)
    ⚈  Recommend schema change
    ⚈  Possibly even a architectural change (EAV is a common problem)

Some common recommendations:

Many-to-Many mapping schema
Speeding up wp_postmeta
explode-implode problem of JOIN + GROUP BY
Pagination via OFFSET - instead "remember where you left off"

Posted June, 2017;   Slowlog: Sep, 2017

More tips are found in the links below.


MySQL Documents by Rick James

HowTo Techniques for Optimizing Tough Tasks:

Partition Maintenance (DROP+REORG) for time series (includes list of PARTITION uses)
Big DELETEs - how to optimize -- and other chunking advice, plus a use for PARTITIONing
    Chunking lengthy DELETE/UPDATE/etc.
Data Warehouse techniques:
    Overview   Summary Tables   High speed ingestion  
Entity-Attribute-Value -- a common, poorly performing, design pattern (EAV); plus an alternative
Find the nearest 10 pizza parlors -- efficient searching on Latitude + Longitude (another PARITION use)
    Lat/Long representation choices
Pagination, not with OFFSET, LIMIT
Techniques on efficiently finding a random row (On beyond ORDER BY RAND())
GUID/UUID Performance (type 1 only)
IP Range Table Performance -- or other disjoint ranges
Rollup Unique User Counts
Alter of a Huge table -- Mostly obviated by 5.6
Latest 10 news articles -- how to optimize the schema and code for such
Build and execute a "Pivot" SELECT (showing rows as columns)
Find largest row for each group ("groupwise max")

Other Tips, Tuning, Debugging, Optimizations, etc...

Rick's RoTs (Rules of Thumb -- lots of tips)
Memory Allocation (caching, etc)
Character Set and Collation problem solver
    Trouble with UTF-8   utf8 Collations   utf8mb4 Collations on 8.0
Converting from MyISAM to InnoDB -- includes differences between them
Compound INDEXes plus other insights into the mysteries of INDEXing
Cookbook for Creating Indexes
    Many-to-many mapping table   wp_postmeta
MySQL Limits -- built-in hard limits
Galera, tips on converting to (Percona XtraDB Cluster, MariaDB 10, or manually installed)
5.7's Query Rewrite -- perhaps 5.7's best perf gain, at least for this forum's users
Best of MySQL Forum -- index of lots of tips, discussions, etc

My slides from conferences
Percona Live 4/2017 - Rick's RoTs (Rules of Thumb) - MySQL/MariaDB
Percona Live 4/2017 - Index Cookbook - MySQL/MariaDB
Percona Live 9/2015 - PARTITIONing - MySQL/MariaDB
(older ones upon request)

Contact me via LinkedIn; be sure to include a brief teaser in the Invite request:   View Rick James's profile on LinkedIn