Difference between revisions of "MySQL/Optimization"
(initial writeup) |
|||
(5 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
== Caching == | == Caching == | ||
− | One thing you should look at is the query cache. By default, the query cache is turned off. You should turn it on, and set it in the tens of megabytes to see how it affects performance (like 80MB for starters). A huge cache will hurt performance (don't give it 4GB just because you have 32GB of RAM). But some amount of cache will definitely improve performance. So you just have to find the sweetspot for your hardware and application. That being said, if your tables are exclusively InnoDB tables, then you might be able to turn query cache off. <ref>Hayden James: https://haydenjames.io/mysql-query-cache-size-performance/</ref> <ref>https://dev.mysql.com/doc/refman/5.7/en/query-cache-status-and-maintenance.html</ref> | + | One thing you should look at is the query cache. By default, the query cache is turned off. You should turn it on, and set it in the tens of megabytes to see how it affects performance (like 80MB for starters). A huge cache will hurt performance (don't give it 4GB just because you have 32GB of RAM). But some amount of cache will definitely improve performance. So you just have to find the sweetspot for your hardware and application. That being said, if your tables are exclusively InnoDB tables, then you might be able to turn query cache off. <ref>Hayden James: https://haydenjames.io/mysql-query-cache-size-performance/</ref> <ref>https://dev.mysql.com/doc/refman/5.7/en/query-cache-status-and-maintenance.html</ref> |
The cache is for SELECT queries obviously. Any insert or update invalidates the cache so you can't get stale data from cache. Low memory prunes indicates how many queries are being removed to make room for new queries that are being cached and the cache prune strategy is LRU (least recently used) so that queries that are seen the most frequently are the ones that get priority for caching. It wouldn't make much sense to cache a query that is rare v. a query that is used on every page load. | The cache is for SELECT queries obviously. Any insert or update invalidates the cache so you can't get stale data from cache. Low memory prunes indicates how many queries are being removed to make room for new queries that are being cached and the cache prune strategy is LRU (least recently used) so that queries that are seen the most frequently are the ones that get priority for caching. It wouldn't make much sense to cache a query that is rare v. a query that is used on every page load. | ||
Line 28: | Line 28: | ||
WHERE VARIABLE_NAME LIKE 'QCACHE%' | WHERE VARIABLE_NAME LIKE 'QCACHE%' | ||
) AS stats; | ) AS stats; | ||
− | |||
− | |||
− | |||
− | |||
</source> | </source> | ||
Line 37: | Line 33: | ||
Look for long-running transactions; and deadlocks | Look for long-running transactions; and deadlocks | ||
− | The best tuning parameters are | + | The best tuning parameters are |
− | + | # <code>innodb_buffer_pool_size</code> as much as you can spare after OS and MySQL | |
− | + | # <code>innodb_log_file_size</code> at least enough for 60 minutes of log writes (because sequential writes to a log file are faster than disk) | |
− | + | # <code>innodb_io_capacity</code> based on your disk IOPS | |
− | + | <ref>Bill Karwin, Percona http://www.slideshare.net/billkarwin/mysql-55-guide-to-innodb-status</ref> <ref>https://www.percona.com/blog/2008/11/21/how-to-calculate-a-good-innodb-log-file-size/</ref> <ref>https://www.percona.com/blog/2011/04/04/innodb-flushing-theory-and-solutions/</ref><ref>https://www.percona.com/blog/2007/11/03/choosing-innodb_buffer_pool_size/</ref> | |
− | + | <source lang="bash"> | |
− | + | SHOW ENGINE INNODB STATUS\G; | |
− | |||
− | <source lang=" | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</source> | </source> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{{References}} | {{References}} | ||
− | |||
− | |||
− |
Revision as of 11:07, 4 August 2016
Caching[edit | edit source]
One thing you should look at is the query cache. By default, the query cache is turned off. You should turn it on, and set it in the tens of megabytes to see how it affects performance (like 80MB for starters). A huge cache will hurt performance (don't give it 4GB just because you have 32GB of RAM). But some amount of cache will definitely improve performance. So you just have to find the sweetspot for your hardware and application. That being said, if your tables are exclusively InnoDB tables, then you might be able to turn query cache off. [1] [2]
The cache is for SELECT queries obviously. Any insert or update invalidates the cache so you can't get stale data from cache. Low memory prunes indicates how many queries are being removed to make room for new queries that are being cached and the cache prune strategy is LRU (least recently used) so that queries that are seen the most frequently are the ones that get priority for caching. It wouldn't make much sense to cache a query that is rare v. a query that is used on every page load.
-- check the settings
SHOW VARIABLES LIKE '%cache%';
-- check the status
SHOW STATUS LIKE 'Qcache%';
-- turn it on
SET GLOBAL query_cache_size = 80000000;
-- Measure performance
-- Uncomment line 2 to check the math
SELECT FORMAT(((QCACHE_HITS / (Qcache_hits + Qcache_inserts + Qcache_not_cached))*100),2) AS query_cache_hit_rate_percentage
--, QCACHE_FREE_BLOCKS, QCACHE_FREE_MEMORY, QCACHE_HITS, QCACHE_INSERTS, QCACHE_LOWMEM_PRUNES, QCACHE_NOT_CACHED, QCACHE_QUERIES_IN_CACHE, QCACHE_TOTAL_BLOCKS
FROM (
SELECT
MAX(IF(VARIABLE_NAME = 'QCACHE_FREE_BLOCKS', VARIABLE_VALUE, NULL)) QCACHE_FREE_BLOCKS,
MAX(IF(VARIABLE_NAME = 'QCACHE_FREE_MEMORY', VARIABLE_VALUE, NULL)) QCACHE_FREE_MEMORY,
MAX(IF(VARIABLE_NAME = 'QCACHE_HITS', VARIABLE_VALUE, NULL)) QCACHE_HITS,
MAX(IF(VARIABLE_NAME = 'QCACHE_INSERTS', VARIABLE_VALUE, NULL)) QCACHE_INSERTS,
MAX(IF(VARIABLE_NAME = 'QCACHE_LOWMEM_PRUNES', VARIABLE_VALUE, NULL)) QCACHE_LOWMEM_PRUNES,
MAX(IF(VARIABLE_NAME = 'QCACHE_NOT_CACHED', VARIABLE_VALUE, NULL)) QCACHE_NOT_CACHED,
MAX(IF(VARIABLE_NAME = 'QCACHE_QUERIES_IN_CACHE', VARIABLE_VALUE, NULL)) QCACHE_QUERIES_IN_CACHE,
MAX(IF(VARIABLE_NAME = 'QCACHE_TOTAL_BLOCKS', VARIABLE_VALUE, NULL)) QCACHE_TOTAL_BLOCKS
FROM information_schema.global_status
WHERE VARIABLE_NAME LIKE 'QCACHE%'
) AS stats;
InnoDB status[edit | edit source]
Look for long-running transactions; and deadlocks
The best tuning parameters are
innodb_buffer_pool_size
as much as you can spare after OS and MySQLinnodb_log_file_size
at least enough for 60 minutes of log writes (because sequential writes to a log file are faster than disk)innodb_io_capacity
based on your disk IOPS
SHOW ENGINE INNODB STATUS\G;
References[edit source]
- ↑ Hayden James: https://haydenjames.io/mysql-query-cache-size-performance/
- ↑ https://dev.mysql.com/doc/refman/5.7/en/query-cache-status-and-maintenance.html
- ↑ Bill Karwin, Percona http://www.slideshare.net/billkarwin/mysql-55-guide-to-innodb-status
- ↑ https://www.percona.com/blog/2008/11/21/how-to-calculate-a-good-innodb-log-file-size/
- ↑ https://www.percona.com/blog/2011/04/04/innodb-flushing-theory-and-solutions/
- ↑ https://www.percona.com/blog/2007/11/03/choosing-innodb_buffer_pool_size/