Showing posts with label Query optimization. Show all posts
Showing posts with label Query optimization. Show all posts

Tuesday, June 12, 2012

How to Boost MySQL Scalability


We face a lot of scalability challenges with clients again and again. The list of point I cannot limit to numbers. However I am giving some basic ideas to scale MySQL Server.

1. Tune queries which are causing performance degradation
Till now the biggest cause of performance buck is unoptimized query. Queries can be functionally correct and meet business requirements, but if they are used without stress tested for high traffic and high load can cause pain.   This is why we often see clients with growing pains, and scalability challenges as their site becomes more popular. This also makes sense. It wouldn’t necessarily be a good use of time to tune a query for some page off in a remote corner of your site, that didn’t receive real-world traffic. So some amount of reactive tuning is common and appropriate.
Enable the slow query log, watch it, analyze it and try to optimize slow queries. Also make sure the log_queries_not_using_indexes flag is set.  Once you’ve found a heavy resource intensive query, optimize it!  Use the EXPLAIN facility, use a profiler, look at index usage and create missing indexes, and understand how it is joining and/or sorting.
2. Employ Master-Master Replication
Master-master active-passive replication, otherwise known as circular replication, can be a boon for high availability, but also for scalability.  That’s because you immediately have a read-only slave for your application to hit as well.  Many web applications exhibit an 80/20 split, where 80% of activity is read or SELECT and the remainder is INSERT and UPDATE.  Configure your application to send read traffic to the slave or rearchitect so this is possible.  This type of horizontal scalability can then be extended further, adding additional read-only slaves to the infrastructure as necessary.
But use it only Active-Passive mode. If you want to use Active-Active replication, make sure you are not using same database on both server at same time. It may cause data inconsistency as MySQL does not having ability for Remote Locking.
3. Use Your Memory
It sounds very basic and straightforward, yet there are often details overlooked.  At minimum be sure to set these:
  • innodb_buffer_pool_size
  • key_buffer_size (MyISAM index caching)
  • query_cache_size
  • thread_cache & table_cache
  • innodb_log_file_size & innodb_log_buffer_size
  • sort_buffer_size, join_buffer_size, read_buffer_size, read_rnd_buffer_size
  • tmp_table_size & max_heap_table_size
4. RAID Your Disk I/O
What is underneath your database?  You don’t know?  Well please find out!  Are you using RAID 5?  This is a big performance hit.  RAID5 is slow for inserts and updates.  It is also almost non-functional during a rebuild if you lose a disk.  Very very slow performance.  What should I use instead?  RAID 10 mirroring and striping, with as many disks as you can fit in your server or raid cabinet.  A database does a lot of disk I/O even if you have enough memory to hold the entire database.  Why?  Sorting requires rearranging rows, as does group by, joins, and so forth.  Plus the transaction log is disk I/O as well!
Are you running on EC2?  In that case EBS is already fault tolerant and redundant.  So give your performance a boost by striping-only across a number of EBS volumes using the Linux md software raid.
5. Tune Key Parameters
These additional parameters can also help a lot with performance.
innodb_flush_log_at_trx_commit=2
This speeds up inserts & updates dramatically by being a little bit lazy about flushing the innodb log buffer.  You can do more research yourself but for most environments this setting is recommended.
innodb_file_per_table
Innodb was developed like Oracle with the tablespace model for storage.  Apparently the kernel developers didn’t do a very good job.  That’s because the default setting to use a single tablespace turns out to be a performance bottleneck.  Contention for file descriptors and so forth.  This setting makes innodb create tablespace and underlying datafile for each table, just like MyISAM does.

Wednesday, May 30, 2012

Basic Performance Tuning Concepts for MySQL

Here is the some common performance tuning concepts/process that I follow to tune the MySQL Server. This is only a basic introduction to performance tuning. For more in-depth tuning, it strongly depends on your systems, data and usage.

Below is the steps I follow to tune MySQL Server.

1.    Query optimization

2.    Data type Optimization

3.    MySQL Server variables optimization

4.    Hardware optimization





1.    Query optimization/Tuning

First, though probably the most important, we look at tuning queries. We check whether they are executing smoothly or not. In particular, we make sure that they’re using indexes, joining on appropriate columns and they’re running quickly. To get the list of those queries which are not using index, executing smoothly or taking more the expected time in execution, we turn on the Slow Query Log for some time, with proper setting of long query time and variables.  At the end we will got the log file with queries which have taken more than expected time in execution.  Run the resulting log through mysqldumpslow, which will produce a summary of the log. This summary will have the detail of query, query execution time, occurrence of query.   This will help you prioritize which queries to tackle first. Then, you can use EXPLAIN to find out what they’re doing, and adjust your indexes accordingly.



Note: - Adding a new index is overhead on I/O. Think before you are adding any index/indexes on the table.



2.    Data type Optimization

In this step we will check weather data type for all columns has been declared correctly or not. We will check it with procedure analyze function. Remember it will calculate/Suggest based on current database size/data.  Before changing it also think about future prospects.



3.    MySQL Server variables optimization

For tuning Innodb performance, the  primary variable is innodb_buffer_pool_size. This is the chunk of memory that InnoDB uses for caching data, indexes and various pieces of information about your database. The bigger, the better. If you can cache all of your data in memory, you’ll see significant performance improvements.

For MyISAM, there is a similar buffer defined by key_buffer_size, though this is only used for indexes, not data. Again, the bigger, the better.

Other variables that are worth investigating for performance tuning are:

query_cache_size - This can be very useful if you have a small number of read queries that are repeated frequently, with no write queries in between. There have been problems with too large a query cache locking up the server, so you will need to experiment to find a value that’s right for you.

innodb_log_file_size - Don’t fall into the trap of setting this to be too large. A large InnoDB log file group is necessary if you have lots of large, concurrent transactions, but comes at the expense of slowing down InnoDB recover, in event of a crash.

sort_buffer_size - Another one that shouldn’t be set too large.

innodb_flush_log_at_trx_commit—How innoDB will commit


4.    Hardware optimization

There are a few recommendations for improving the performance of MySQL by upgrading your hardware:

·         Use a 64-bit processor, operating system and MySQL binary. This will allow you to address lots of RAM.

·         Speaking of RAM, buy lots of it. Enough to fit all of your data and indexes, if you can.

·         If you can’t fit all of your data into RAM, you’ll need fast disks, RAID if you can. Have multiple disks, so you can separate your data files, OS files and log files onto different physical disks.