MySQL Performance Tuning Best Practices
MySQL Performance Tuning Best Practices
Agenda
Overview Hardware and OS Storage Engines Connections Sessions Query Cache Queries Schema Partitions What if I need more help?
Copyright 2010 Oracle The Worlds Most Popular Open Source Database The Worlds Most Popular Open Source Database
Overview
Cover the main steps Show at least one example for each step Examples are things I run into most commonly in the field Include links to MySQL manual for additional information This will be technical! You cannot become a performance tuning wizard in 45 minutes - PT Class is 4 day class
http://www.mysql.com/training/courses/performance_tuning.html
You monitor how well your system variables are configured using Status Variables
mysql> SHOW STATUS [LIKE <str>]; linux1> mysqladmin -u <user> -p extended linux1> mysqladmin ... ex -i 15 -r | grep -v 0 http://dev.mysql.com/doc/refman/5.1/en/server-status-variables.html
Never make a change in production first Have a good benchmark or reliable load Start with a good baseline Only change 1 thing at a time
identify a set of possible changes try each change separately try in combinations of 2, then 3, etc.
Rules of Tuning
- http://osdldbt.sourceforge.net/ - http://samurai-mysql.blogspot.com/2009/03/settingup-dbt-
supersmack mybench
Perfect Hardware?
4-8 Cores now, 8-16 cores for 5.4 and up x86_64 - 64 bit for more memory is important Linux or Solaris best, Windows and Unix also fine. RAID 10 for most, RAID 5 OK if very read intensive Hardware RAID battery backed up cache critical!
- More disks are always better!
- 4+ recommended, 8-16 can increase IO performance if needed
Allocate swap space (at least 1/2 of RAM size) Set vm.swappiness = 0 and use O_DIRECT Set /sys/block/sdX/queue/scheduler = deadline or noop Filesystem Tuning
Linux Tuning (Yoshinori Matsunobu) Install at (Yoshinori Matsunobu)package) least sar, mpstat, iostat (sysstat Oprofile, gdb and SystemTap(stap) are recommended (Yoshinori Matsunobu)
ext3: tune2fs O dir_index -c l i 0 xfs: nobarrier Make sure write cache with battery is enabled http://en.oreilly.com/mysql2010/public/schedule/detail/13252
MyISAM
Fastest storage engine 3x or more when appropriate
Most web applications Perfect for web search databases 80/20 read/modify or higher pure inserts and deletes with partitions or merge engine no transactions reporting DB/ Data Warehouse
Most compact data of all non-compressed engines Table locking Not ACID compliant, non-transactional Supports concurrent inserts Full-Text and Geospatial support http://dev.mysql.com/doc/refman/5.1/en/myisam-storage-en
MyISAM Tuning
The primary tuning factor in MyISAM are its two caches:
key_buffer_cache - should be 25% of available memory system cache - leave 75% of available memory free
You can define multiple key buffers You can pre-load the key buffers For more details on configuring the MyISAM key cache see:
http://dev.mysql.com/doc/refman/5.1/en/myisam-key-cache.html
mysql>show status like 'Key%' ; Key_blocks_not_flushed - Dirty key blocks not flushed to disk Key_blocks_unused - unused blocks in the cache Key_blocks_used - used Blocks in the cache % of cache free : Key_blocks_unused /(Key_blocks_unused + Key_blocks_used) Key_read_requests - key requests to the cache Key_reads - times a key read request went to disk Cache read hit % : Key_reads / Key_read_requests Key_write_requests - key write request to cache Key_writes - times a key write request went to disk Cache write hit % : Key_writes / Key_write_request cat /proc/meminfo to see the system cache in linux
MemFree + Cached = memory available for system cache
Copyright 2010 Oracle The Worlds Most Popular Open Source Database
InnoDB
Transactional and fully ACID compliant Behavior most like traditional databases such as Oracle, DB2, SQL Server, etc. Data size is normally 2-3 X MyISAM MVCC = Non-blocking reads in most cases Fast, reliable recovery from crashes with zero committed data loss Always clustered on the primary key
Lookups by primary key, very fast Range scans on primary key also very fast Non-Primary key lookups use the primary key to find the record, this means 2 key lookups Important to keep primary key small
http://dev.mysql.com/doc/refman/5.1/en/innodb.html
InnoDB
Unlike MyISAM InnoDB uses a single cache for both index and data
Innodb_buffer_pool_size - should be 70-80% of available memory. It is not uncommon for this to be very large, i.e. 44GB on a system with 40GB of memory Make sure its not set so large as to cause swapping! mysql>show status like 'Innodb_buffer%' ; Innodb_flush_method = O_DIRECT
InnoDB can use direct IO on systems that support it, linux, FreeBSD, and Solaris. For more InnoDB tuning see
http://dev.mysql.com/doc/refman/5.1/en/innodb-tuning-troubleshootin
Transactions per Minute %user 1125.44 1863.19 4385.18 36784.76 2% 3% 5.5% 36%
DBT-2 benchmark (write intensive) 20-25GB hot data (200 warehouses, running 1 hour) Nehalem 2.93GHz x 8 cores, MySQL 5.5.2, 4 RAID1+0 HDDs RAM size affects everything. Not only for SELECT, but also for INSERT/UPDATE/DELETE INSERT: Random reads/writes happen when inserting into indexes in random order UPDATE/DELETE: Random reads/writes happen when modifying records
Connections
MySQL Caches the threads used by a connection
thread_cache_size - Number of threads to cache Setting this to 100 or higher is not unusual
Only an issue is you create and drop a lot of connections, i.e. PHP Overhead is usually about 250k per thread Aborted_clients http://dev.mysql.com/doc/refman/5.1/en/communication-error Aborted_connections http://dev.mysql.com/doc/refman/5.1/en/communication-error
Sessions
Some session variables control space allocated by each session (connection)
Setting these to small can give bad performance Setting these too large can cause the server to swap! Can be set by connection Set small be default, increase in connections that need it
SET SORT_BUFFER_SIZE=1024*1024*128
sort_buffer_size - Used for ORDER BY, GROUP BY, SELECT DISTINCT, UNION DISTINCT
Monitor Sort_merge_passes < 1-2 an hour optimal Usually a problem in a reporting or data warehouse database
Query Cache
MySQLs Jekyll and Hyde of performance tuning options, when it is useful it really helps, when it hurts, it really hurts MySQL Query Cache caches both the query and the full result set
query_cache_type - Controls behavior
0 or OFF - Not used (buffer may still be allocated) 1 or ON cache all unless SELECT SQL_NO_CACHE (DEFAULT) 2 or DEMAND cache none unless SELECT SQL_CACHE
Identical queries returning identical data are used often No or rare inserts, updates or deletes
Best Practice Set to DEMAND Add SQL_CACHE to appropriate queries See http://dev.mysql.com/doc/refman/5.1/en/query-cache-configuratio
Copyright 2010 Oracle The Worlds Most Popular Open Source Database
Queries I
Often the # 1 issue in overall performance Always, Always have your slow query log on!
http://dev.mysql.com/doc/refman/5.1/en/slow-query-log.html Use: log_queries_not_using_indexes Check it regularly Use mysqldumpslow : http://dev.mysql.com/doc/refman/5.1/en/mysqldumpslow.html
Best practice is to automate running mysqldumpslow every morning and email results to DBA, DBDev, etc.
http://dev.mysql.com/doc/refman/5.1/en/using-explain.html
Select_scan - Number of full table scans Select_full_join - Joins without indexes MySQL Query Analyzer
http://www.mysql.com/products/enterprise/query.html
Copyright 2010 Oracle The Worlds Most Popular Open Source Database
Queries II
The IN clause in MySLQ is very fast!
Select ... Where idx IN(1,23,345,456) Much faster than a join I have done tests with 80,000 items in the in list
1,000-2,000 not unusual
Use union all when appropriate, default is union distinct! Understand left/right joins and use only when needed http://dev.mysql.com/doc/refman/5.1/en/query-speed.html
Copyright 2010 Oracle The Worlds Most Popular Open Source Database
Centralized monitoring of Queries across all servers with no reliance on Slow Query Logs Aggregated view of query execution counts, time, and rows returned = total query expense Saves time/effort parsing atomic executions for total query expense Saves time finding most expensive queries across all Production, Dev, and QA servers so SQL can be tuned. Finds code problems before your customers do.
Copyright 2010 Oracle The Worlds Most Popular Open Source Database
Schema I
Too many indexes slow down inserts/deletes
Use only the indexes you must have Check often
mysql>show create table tabname ; Dont duplicate leading parts of compound keys
index key123 (col1,col2,col3) index key12 (col1,col2) <- Not needed! index key1 (col1) <-- Not needed!
Use prefix indexes on large keys Best indexes are 16 bytes/chars or less Indexes bigger than 32 bytes/chars should be looked at very closely
should have there own cache if in MyISAM
For large strings that need to be indexed, i.e. URLs, consider using a separate column using the MySQL MD5 to create a hash key.
Copyright 2010 Oracle The Worlds Most Popular Open Source Database
Schema II
Size = performance, smaller is better
Size right! Do not automatically use 255 for VARCHAR
Temp tables, most caches, expand to full size
Use procedure analyse to determine the optimal types given the values in your table
http://dev.mysql.com/doc/refman/5.1/en/procedure-analyse.html
Only works with Range and List partitioning Very useful for rolling date/time range Can be very useful even for small increments, i.e.1 hour Very fast, can be ~ 1-2 Secs
http://en.oreilly.com/mysql2010/public/schedule/detail/13383
Good for:
Applications with poor response times, hit wall recently? Solving system scalability issues Reduction of hardware $$$ outlay Prevention of new complex scaling architecture Load testing, benchmarking, capacity planning
Response Time
Starvation
Copyright 2010 Oracle
Concurrency
What we did:
Results:
Adding multi-column indexes that are optimized for some queries Column data type optimizations The removal of unnecessary tables The removal of unnecessary indexes
68% faster on warm benchmark Dramatic reduction in disk i/o No more database crashing and corruption
The presentation is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracles products remains at the sole discretion of Oracle.