<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>RICOTEK IT CONSULTING - RICOTEK IT CONSULTING</title>
	<atom:link href="http://ricotek.net/feed" rel="self" type="application/rss+xml" />
	<link>http://ricotek.net</link>
	<description></description>
	<lastBuildDate>Tue, 11 Sep 2012 03:01:37 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>Optimize Apache and MySQL</title>
		<link>http://ricotek.net/uncategorized/optimize-apache-and-mysql?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=optimize-apache-and-mysql</link>
		<comments>http://ricotek.net/uncategorized/optimize-apache-and-mysql#comments</comments>
		<pubDate>Sat, 18 Feb 2012 19:40:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://ricotek.net/?p=942</guid>
		<description><![CDATA[A hot topic for anyone running MySQL and Apache on any machine is optimization and I hope to quickly explain how to optimize MySQL and where to tweak Apache to help with it’s operational efficiency as well. First things first … A few common things to possibly turn on, install, … <a href="http://ricotek.net/uncategorized/optimize-apache-and-mysql"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>A hot topic for anyone running MySQL and Apache on any machine is optimization and I hope to quickly explain how to optimize MySQL and where to tweak Apache to help with it’s operational efficiency as well.</p>
<h1>First things first …</h1>
<p>A few common things to possibly turn on, install, or enable:</p>
<ul>
<li>APC (Another PHP Cache)</li>
<li>Memcached</li>
</ul>
<h1>MySQL Optimization</h1>
<p>The easiest way (and the quickest) to determine what can be done to optimize MySQL is to use a script called mysqltuner.pl. The really interesting thing about this script is that to get it you simply run the following:</p>
<p>wget mysqltuner.pl</p>
<p>After you’ve gotten this script run it with your perl interpreter:</p>
<p>perl mysqltuner.pl</p>
<p>It will prompt you for your username and password for mysql and then print out a nice report outlining how your mysql daemon has been running. Here’s an example of this output:</p>
<p>&gt;&gt; MySQLTuner 1.0.1 – Major Hayden<br />
&gt;&gt; Bug reports, feature requests, and downloads at http://mysqltuner.com/<br />
&gt;&gt; Run with ‘–help’ for additional options and output filtering<br />
Please enter your MySQL administrative login: root<br />
Please enter your MySQL administrative password:</p>
<p>——– General Statistics ————————————————–<br />
[--] Skipped version check for MySQLTuner script<br />
[OK] Currently running supported MySQL version 5.0.90-log<br />
[OK] Operating on 32-bit architecture with less than 2GB RAM</p>
<p>——– Storage Engine Statistics ——————————————-<br />
[--] Status: -Archive -BDB -Federated +InnoDB -ISAM -NDBCluster<br />
[--] Data in MyISAM tables: 28M (Tables: 96)<br />
[--] Data in InnoDB tables: 1M (Tables: 55)<br />
[!!] Total fragmented tables: 2</p>
<p>——– Performance Metrics ————————————————-<br />
[--] Up for: 1h 39m 49s (24K q [4.163 qps], 354 conn, TX: 9M, RX: 34M)<br />
[--] Reads / Writes: 60% / 40%<br />
[--] Total buffers: 148.6M global + 960.0K per thread (100 max threads)<br />
[OK] Maximum possible memory usage: 242.3M (11% of installed RAM)<br />
[OK] Slow queries: 0% (0/24K)<br />
[OK] Highest usage of available connections: 28% (28/100)<br />
[OK] Key buffer size / total MyISAM indexes: 64.0K/6.3M<br />
[OK] Key buffer hit rate: 99.6% (164K cached / 682 reads)<br />
[OK] Query cache efficiency: 81.3% (14K cached / 17K selects)<br />
[OK] Query cache prunes per day: 0<br />
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 463 sorts)<br />
[!!] Joins performed without indexes: 42<br />
[OK] Temporary tables created on disk: 12% (54 on disk / 417 total)<br />
[OK] Thread cache hit rate: 70% (106 created / 354 connections)<br />
[!!] Table cache hit rate: 2% (48 open / 2K opened)<br />
[OK] Open file limit used: 9% (95/1K)<br />
[OK] Table locks acquired immediately: 98% (7K immediate / 7K locks)<br />
[!!] Connections aborted: 7%<br />
[OK] InnoDB data size / buffer pool: 1.0M/4.0M</p>
<p>——– Recommendations —————————————————–<br />
General recommendations:<br />
Run OPTIMIZE TABLE to defragment tables for better performance<br />
MySQL started within last 24 hours – recommendations may be inaccurate<br />
Adjust your join queries to always utilize indexes<br />
Increase table_cache gradually to avoid file descriptor limits<br />
Your applications are not closing MySQL connections properly<br />
Variables to adjust:<br />
join_buffer_size (&gt; 128.0K, or always use indexes with joins)<br />
table_cache (&gt; 48)</p>
<p>The first thing to notice is that mysql should be running for 24 to 48 hours before you trust the results of this script. The second thing to acknowledge is that it isn’t omniscient. Understanding how these parameters affect your memory footprint and your runtime efficiency are what we’re most interested in though.</p>
<h1>Glossary of Parameters</h1>
<p>The best source of my.cnf parameters is of course the MySQL documentation, but I’ll clarify a few of the more pertinent items from the above output.</p>
<ul>
<li>Maximum Possible Memory – This is not the actual hard limit on your memory usage but a calculated theoretical maximum based on the parameters in your my.cnf and if this is over ~90% you may use your swap more than you want to. After making any changes I suggest you check this to make sure you haven’t over-allocated yourself.</li>
<li>Highest Usage of Available Connections – This is the historical max connections used by mysql and if it’s at 100% this isn’t a guarantee that you need to increase max_connections but may just indicate that your connections spiked once. That being said I recommend following its advice if you have the memory for it.</li>
<li>Query Cache Efficiency – The hit rate for the cache on your queries (I hope you have enabled). As with any hash table if you’re not hitting what’s in the top bucket you need to increase the number of buckets.</li>
<li>Temporary Tables Created on Disk – This can be a finicky parameter to get right and is the first place I would recommend cutting if you don’t have the memory to run mysql like you would want, but if you do have the memory then up this as far as you can within reason.</li>
<li>Thread Cache Hit Rate – Just like any other cache.</li>
<li>Table Cache Hit Rate – Just like any other cache.</li>
</ul>
<h1>Fragmented Tables</h1>
<p>If you noticed the fragmented tables along with the recommendation to run OPTIMIZE TABLE that’s not something that will typically slow mysql down noticeably with today’s disks, but if you want to defragment them I recommend reading <a href="http://www.dufault.info/blog/a-script-to-optimize-fragmented-tables-in-mysql/">this article on the topic</a>.</p>
<h1>Apache Tweaking</h1>
<p>The following parameters are usually in httpd.conf unless you run a distribution that organizes apache in an easier to work with manner (my preference of course is Gentoo which stores these parameters in: 00_mpm.conf).</p>
<p>The parameters for tweaking apache’s processes depend on which worker module you have in use. The following is the pertinent sections from my configuration:</p>
<p>#prefork MPM<br />
# This is the default MPM if USE=-threads<br />
#<br />
# MinSpareServers: Minimum number of idle child server processes<br />
# MaxSpareServers: Maximum number of idle child server processes</p>
<p>StartServers 5<br />
MinSpareServers 5<br />
MaxSpareServers 10<br />
MaxClients 50<br />
MaxRequestsPerChild 500</p>
<p># worker MPM<br />
# This is the default MPM if USE=threads<br />
#<br />
# MinSpareThreads: Minimum number of idle threads available to handle request spikes<br />
# MaxSpareThreads: Maximum number of idle threads<br />
# ThreadsPerChild: Number of threads created by each child process</p>
<p>StartServers 2<br />
MinSpareThreads 15<br />
MaxSpareThreads 50<br />
ThreadsPerChild 25<br />
MaxClients 150<br />
MaxRequestsPerChild 1000</p>
<p>These parameters are pretty self explanatory but just for completeness’ sake I’ll do a small recap on these here:</p>
<p>* StartServers – The number of servers to have running and handling connections at first launch.<br />
* MinSpareServers – The minimum number of servers to have running not currently handling connections.<br />
* MaxSpareServers – The maximum number of servers to have running not currently handling connections.<br />
* MaxClients – The maximum number of clients that can simultaneously connect to Apache.<br />
* MaxRequestsPerChild – The maximum number of requests that a child will respond to before terminating.</p>
<p>Using these parameters we can control the amount of memory that Apache will consume at the cost of other things we may want to have like lots of connections or many sequential requests.</p>
]]></content:encoded>
			<wfw:commentRss>http://ricotek.net/uncategorized/optimize-apache-and-mysql/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Config file</title>
		<link>http://ricotek.net/uncategorized/mysql-config-file?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-config-file</link>
		<comments>http://ricotek.net/uncategorized/mysql-config-file#comments</comments>
		<pubDate>Sat, 18 Feb 2012 19:30:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://ricotek.net/?p=939</guid>
		<description><![CDATA[Below are notes on some of the important variables, I took down while tuning the config file. query_cache_size: MySQL 4 provides one feature that can prove very handy &#8211; a query cache. In a situation where the database has to repeatedly run the same queries on the same data set, … <a href="http://ricotek.net/uncategorized/mysql-config-file"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>Below are notes on some of the important variables, I took down while tuning the config file.</p>
<ol>
<li>query_cache_size:
<ul>
<li>MySQL 4 provides one feature that can prove very handy &#8211; a query cache. In a situation where the database has to repeatedly run the same queries on the same data set, returning the same results each time, MySQL can cache the result set, avoiding the overhead of running through the data over and over and is extremely helpful on busy servers.</li>
</ul>
</li>
<li>key_buffer_size:
<ul>
<li>The value of key_buffer_size is the size of the buffer used with indexes. The larger the buffer, the faster the SQL command will finish and a result will be returned. The rule-of-thumb is to set the key_buffer_size to at least a quarter, but no more than half, of the total amount of memory on the server. Ideally, it will be large enough to contain all the indexes (the total size of all .MYI files on the server).</li>
<li>A simple way to check the actual performance of the buffer is to examine four additional variables: key_read_requests, key_reads, key_write_requests, and key_writes.</li>
<li>If you divide the value of key_read by the value of key_reads_requests, the result should be less than 0.01. Also, if you divide the value of key_write by the value of key_writes_requests, the result should be less than 1.</li>
</ul>
</li>
<li>table_cache:
<ul>
<li>The default is 64. Each time MySQL accesses a table, it places it in the cache. If the system accesses many tables, it is faster to have these in the cache. MySQL, being multi-threaded, may be running many queries on the table at one time, and each of these will open a table. Examine the value of open_tables at peak times. If you find it stays at the same value as your table_cache value, and then the number of opened_tables starts rapidly increasing, you should increase the table_cache if you have enough memory.</li>
</ul>
</li>
<li>sort_buffer:
<ul>
<li>The sort_buffer is very useful for speeding up myisamchk operations (which is why it is set much higher for that purpose in the default configuration files), but it can also be useful everyday when performing large numbers of sorts.</li>
</ul>
</li>
<li>read_rnd_buffer_size:
<ul>
<li>The read_rnd_buffer_size is used after a sort, when reading rows in sorted order. If you use many queries with ORDER BY, upping this can improve performance. Remember that, unlike key_buffer_size and table_cache, this buffer is allocated for each thread. This variable was renamed from record_rnd_buffer in MySQL 4.0.3. It defaults to the same size as the read_buffer_size. A rule-of-thumb is to allocate 1KB for each 1MB of memory on the server, for example 1MB on a machine with 1GB memory.</li>
</ul>
</li>
<li>thread_cache:
<ul>
<li>If you have a busy server that&#8217;s getting a lot of quick connections, set your thread cache high enough that the Threads_created value in SHOW STATUS stops increasing. This should take some of the load off of the CPU.</li>
</ul>
</li>
<li>tmp_table_size:
<ul>
<li>&#8220;Created_tmp_disk_tables&#8221; are the number of implicit temporary tables on disk created while executing statements and &#8220;created_tmp_tables&#8221; are memory-based. Obviously it is bad if you have to go to disk instead of memory all the time.</li>
</ul>
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://ricotek.net/uncategorized/mysql-config-file/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Optimize MySQL performance with mysqltuner</title>
		<link>http://ricotek.net/uncategorized/optimize-mysql-performance-with-mysqltuner?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=optimize-mysql-performance-with-mysqltuner</link>
		<comments>http://ricotek.net/uncategorized/optimize-mysql-performance-with-mysqltuner#comments</comments>
		<pubDate>Sat, 18 Feb 2012 19:06:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://ricotek.net/?p=932</guid>
		<description><![CDATA[Optimize MySQL performance with mysqltuner Tuesday, December 22, 2009 posted by Till The following tutorial describes the steps to optimize the performance of a MySQL database with the mysqltuner script. Login to your server on the shell, then execute the following commands: Download the mysqltuner script: cd /usr/local/bin wget http://mysqltuner.pl/mysqltuner.pl … <a href="http://ricotek.net/uncategorized/optimize-mysql-performance-with-mysqltuner"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<h2>Optimize MySQL performance with mysqltuner</h2>
<div>Tuesday, December 22, 2009 posted by Till</div>
<p>The following tutorial describes the steps to optimize the performance of a MySQL database with the mysqltuner script.</p>
<p>Login to your server on the shell, then execute the following commands:</p>
<p>Download the mysqltuner script:</p>
<p>cd /usr/local/bin<br />
wget http://mysqltuner.pl/mysqltuner.pl<br />
chmod +x mysqltuner.pl</p>
<p>Run mysqltuner</p>
<p>/usr/local/bin/mysqltuner.pl</p>
<p>Then enter root as username and the mysql root password.</p>
<p>You will get a output similar to this:</p>
<p>root@v221:/usr/local/bin# /usr/local/bin/mysqltuner.pl</p>
<p>&gt;&gt;  MySQLTuner 1.0.1 – Major Hayden &lt;major@mhtx.net&gt;<br />
&gt;&gt;  Bug reports, feature requests, and downloads at http://mysqltuner.com/<br />
&gt;&gt;  Run with ‘–help’ for additional options and output filtering<br />
Please enter your MySQL administrative login: root<br />
Please enter your MySQL administrative password:</p>
<p>——– General Statistics ————————————————–<br />
[--] Skipped version check for MySQLTuner script<br />
[OK] Currently running supported MySQL version 5.0.51a-24+lenny2<br />
[!!] Switch to 64-bit OS – MySQL cannot currently use all of your RAM</p>
<p>——– Storage Engine Statistics ——————————————-<br />
[--] Status: +Archive -BDB -Federated +InnoDB -ISAM -NDBCluster<br />
[--] Data in MyISAM tables: 26M (Tables: 215)<br />
[!!] InnoDB is enabled but isn’t being used<br />
[!!] Total fragmented tables: 33</p>
<p>——– Performance Metrics ————————————————-<br />
[--] Up for: 96d 23h 3m 41s (10M q [1.239 qps], 686K conn, TX: 701M, RX: 1B)<br />
[--] Reads / Writes: 44% / 56%<br />
[--] Total buffers: 58.0M global + 2.6M per thread (100 max threads)<br />
[OK] Maximum possible memory usage: 320.5M (12% of installed RAM)<br />
[OK] Slow queries: 0% (20/10M)<br />
[OK] Highest usage of available connections: 33% (33/100)<br />
[OK] Key buffer size / total MyISAM indexes: 16.0M/8.5M<br />
[OK] Key buffer hit rate: 99.9% (57M cached / 30K reads)<br />
[OK] Query cache efficiency: 78.6% (5M cached / 6M selects)<br />
[!!] Query cache prunes per day: 483<br />
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 408K sorts)<br />
[!!] Temporary tables created on disk: 36% (269K on disk / 745K total)<br />
[OK] Thread cache hit rate: 99% (427 created / 686K connections)<br />
[!!] Table cache hit rate: 2% (64 open / 3K opened)<br />
[OK] Open file limit used: 11% (120/1K)<br />
[OK] Table locks acquired immediately: 99% (3M immediate / 3M locks)</p>
<p>——– Recommendations —————————————————–<br />
General recommendations:<br />
Add skip-innodb to MySQL configuration to disable InnoDB<br />
Run OPTIMIZE TABLE to defragment tables for better performance<br />
Enable the slow query log to troubleshoot bad queries<br />
When making adjustments, make tmp_table_size/max_heap_table_size equal<br />
Reduce your SELECT DISTINCT queries without LIMIT clauses<br />
Increase table_cache gradually to avoid file descriptor limits<br />
Variables to adjust:<br />
query_cache_size (&gt; 16M)<br />
tmp_table_size (&gt; 32M)<br />
max_heap_table_size (&gt; 16M)<br />
table_cache (&gt; 64)</p>
<p>The script recommends to adjust or add the following variables in the mysql my.cnf file. The location of my.cnf is normally /etc/my.cnf or /etc/mysql/my.cnf depending on the Linux distribution that is installed on your server.</p>
<p>Open the my.cnf file:</p>
<p>vi /etc/mysql/my.cnf</p>
<p>and increase or set the variables in the [mysqld] section of the file. Mine looks now like this:</p>
<p>[mysqld]<br />
#<br />
# * Basic Settings<br />
#<br />
user            = mysql<br />
pid-file        = /var/run/mysqld/mysqld.pid<br />
socket          = /var/run/mysqld/mysqld.sock<br />
port            = 3306<br />
basedir         = /usr<br />
datadir         = /var/lib/mysql<br />
tmpdir          = /tmp<br />
language        = /usr/share/mysql/english<br />
skip-external-locking<br />
#<br />
# Instead of skip-networking the default is now to listen only on<br />
# localhost which is more compatible and is not less secure.<br />
bind-address            = 127.0.0.1<br />
#<br />
# * Fine Tuning<br />
#<br />
key_buffer              = 16M<br />
max_allowed_packet      = 16M<br />
thread_stack            = 128K<br />
thread_cache_size       = 8<br />
# This replaces the startup script and checks MyISAM tables if needed<br />
# the first time they are touched<br />
myisam-recover          = BACKUP<br />
#max_connections        = 100<br />
table_cache            = 128<br />
#thread_concurrency     = 10<br />
#<br />
# * Query Cache Configuration<br />
#<br />
query_cache_limit       = 1M</p>
<p>query_cache_size        = 32M<br />
tmp_table_sizee        = 64M<br />
max_heap_table_sizee        = 32M</p>
<p>Then save the file and restart mysql. After a few hours, rerun mysqltuner and check again if the values are fine now or if the have to be increased to a higher value.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://ricotek.net/uncategorized/optimize-mysql-performance-with-mysqltuner/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Optimization from a CTO</title>
		<link>http://ricotek.net/uncategorized/mysql-optimization-from-a-cto?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-optimization-from-a-cto</link>
		<comments>http://ricotek.net/uncategorized/mysql-optimization-from-a-cto#comments</comments>
		<pubDate>Sat, 18 Feb 2012 19:03:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://ricotek.net/?p=929</guid>
		<description><![CDATA[Tim CTO, Digital Content Solutions MySQL settings, many concurrent users. I run a site for a client that has over 3000 users that log in for about 5-7 hours per day each. So, at peak times, we have to handle about 2000 concurrent users. When configured correctly, PHP and MySQL … <a href="http://ricotek.net/uncategorized/mysql-optimization-from-a-cto"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>Tim<br />
CTO, Digital Content Solutions</p>
<p>MySQL settings, many concurrent users.<br />
I run a site for a client that has over 3000 users that log in for about 5-7 hours<br />
per day each. So, at peak times, we have to handle about 2000 concurrent users.<br />
When configured correctly, PHP and MySQL can handle this load wonderfully on fairly<br />
cheap Intel architecture. First off, hardware.</p>
<p>1) It is better to have 2 separate servers for Apache/PHP and MySQL with the Linux of your choice.<br />
2) Try not to run too much else on either box; leave the resources for Apache/PHP and MySQL.</p>
<p>Here are the specs on each box in my config:<br />
1) Apache/PHP: Pentium 3, 600 MHZ, 512 megs ram.<br />
2) MySQL: Dual Pentium 3, 750 MHZ (1500 MHZ total), 2 gigs ram.</p>
<p>The reason for this configuration is that it is very database heavy;<br />
it is a members only web site with username and password required for login, fully personalized.<br />
It is an online school, so each student has their suite of tools for attending school,<br />
their courses, report cards, time logging, and much more. Teachers have web based tools to create<br />
their courses, including lessons, text to speech audio, and more.</p>
<p>1) PHP coding: be sure to use persistent connections!<br />
Opening and closing a connection from your Apache/PHP box to your MySQL box is a very heavy load.<br />
By using persistent connections, a high capacity site will open connections and share them to<br />
<a id="KonaLink3" href="http://www.linuxforums.org/forum/servers/79489-mysql-tunning-optimization.html#"><span style="color: blue;">exchange</span></a> data rather than opening a connection on each <a id="KonaLink4" href="http://www.linuxforums.org/forum/servers/79489-mysql-tunning-optimization.html#"><span style="color: blue;">pagerequest</span></a>, sending the data, then closing,<br />
and repeating that process at least once for every user click!<br />
Be sure to use &#8220;mysql_pconnect&#8221; instead of &#8220;mysql_connect&#8221; and also that appropriate changes are made<br />
in &#8220;php.ini&#8221; or overridden by using the <a id="KonaLink5" href="http://www.linuxforums.org/forum/servers/79489-mysql-tunning-optimization.html#"><span style="color: blue;">command</span></a> &#8221;ini_set&#8221;.<br />
You can find more documentation on doing this at the php web site.</p>
<p>2) Apache set up (&#8220;httpd.conf&#8221;): I&#8217;ve changed these various settings, and played with them until they<br />
seem to keep the most &#8220;idle %&#8221; reported in &#8220;top&#8221;.<br />
MinSpareServers 10<br />
MaxSpareServers 20<br />
StartServers 70<br />
MaxClients 255</p>
<p>3) Mysql set up (&#8220;my.cnf&#8221;). The MySQL config file, my.cnf.<br />
Here is what to add under the [mysqld] heading.<br />
The two lines, &#8220;max_connections&#8221; and &#8220;max_user_connections&#8221; are where the magic happens.<br />
Since your Apache/PHP box is connecting to MySQL, it appears as a single user.<br />
MySQL defaults to 1 max connection, with 1 max connection per user. The following lines make<br />
it so your Apache/PHP box can connect to your MySQL box up to the number you have set &#8220;MaxClients&#8221;<br />
to in the Apache config above. By using persistent connections, you can pretty much get Apache up,<br />
have it connect to MySQL upon start up, and just use the persistent connections to pass data between<br />
the two boxes rather than opening connections. Its much more efficient that way.<br />
set-variable = max_connections = 300<br />
(this must be higher than &#8220;MaxClients&#8221; set in Apache, or you won&#8217;t fully maximize use)<br />
set-variable = max_user_connections = 300<br />
set-variable = table_cache=1200<br />
(max number of tables in join multiplied by max_user_connections)</p>
<p>A few other MySQL tunings:<br />
set-variable = max_allowed_packet=1M (sanity check to stop runaway queries)<br />
set-variable = max_connect_errors=999999<br />
(stop mysqld from shutting down if there are connect errors &#8211; this defaults to 1 error and mysqld stops!)</p>
]]></content:encoded>
			<wfw:commentRss>http://ricotek.net/uncategorized/mysql-optimization-from-a-cto/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Optimize MySQL</title>
		<link>http://ricotek.net/uncategorized/optimize-mysql?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=optimize-mysql</link>
		<comments>http://ricotek.net/uncategorized/optimize-mysql#comments</comments>
		<pubDate>Sat, 18 Feb 2012 19:01:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://ricotek.net/?p=927</guid>
		<description><![CDATA[What one can and should optimize Hardware OS / libraries SQL server (setup and queries) API Application Optimizing hardware for MySQL If you need big tables ( &#62; 2G), you should consider using 64 bit hardware like Alpha, Sparc or the upcoming IA64. As MySQL uses a lot of 64 … <a href="http://ricotek.net/uncategorized/optimize-mysql"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<div>
<h1>What one can and should optimize</h1>
<ul>
<li>Hardware</li>
<li>OS / libraries</li>
<li>SQL server (setup and queries)</li>
<li>API</li>
<li>Application</li>
</ul>
<hr />
<h1>Optimizing hardware for MySQL</h1>
<p><span style="font-size: small;"><span class="Apple-style-span" style="line-height: 24px;"><br />
</span></span></div>
<ul>
<li>If you need big tables ( &gt; 2G), you should consider using 64 bit hardware like Alpha, Sparc or the upcoming IA64. As MySQL uses a lot of 64 bit integers internally, 64 bit CPUs will give much better performance.</li>
<li>For large databases, the optimization order is normally RAM, Fast disks, CPU power.</li>
<li>More RAM can speed up key updates by keeping most of the used key pages in RAM.</li>
<li>If you are not using transaction-safe tables or have big disks and want to avoid long file checks, a UPS is good idea to be able to take the system down nicely in case of a power failure.</li>
<li>For systems where the database is on a dedicated server, one should look at 1G Ethernet. Latency is as important as throughput.</li>
</ul>
<hr />
<h1>Optimizing disks</h1>
<ul>
<li>Have one dedicated disk for the system, programs and for temporary files. If you do very many changes, put the update logs and transactions logs on dedicated disks.</li>
<li>Low seek time is important for the database disk; For big tables you can estimate that you will need: <tt>log(row_count) / log(index_block_length/3*2/(key_length + data_ptr_length))+1</tt> seeks to find a row. For a table with 500,000 rows indexing a medium int: <tt>log(500,000)/log(1024/3*2/(3+4)) +1 = 4</tt> seeks The above index would require:<tt>500,000 * 7 * 3/2 = 5.2M</tt>. In real life, most of the blocks will be buffered, so probably only 1-2 seeks are needed.</li>
<li>For writes you will need (as above) 4 seek requests, however, to find where to place the new key, and normally 2 seeks to update the index and write the row.</li>
<li>For REALLY big databases, your application will be bound by the speed of your disk seeks, which increase by <tt>N log N</tt> as you get more data.</li>
<li>Split databases and tables over different disks. In MySQL you can use symbolic links for this.</li>
<li>Striping disks (RAID 0) will increase both read and write throughput.</li>
<li>Striping with mirroring (RAID 0+1) will give you safety and increase the read speed. Write speed will be slightly lower.</li>
<li>Don&#8217;t use mirroring or RAID (except RAID 0) on the disk for temporary files or for data that can be easily re-generated..</li>
<li>On Linux use <code>hdparm -m16 -d1</code> on the disks on boot to enable reading/writing of multiple sectors at a time, and DMA. This may increase the response time by 5-50 %.</li>
<li>On Linux, mount the disks with <code>async</code> (default) and <code>noatime</code>.</li>
<li>For some specific application, one may want to have a ram disk for some very specific tables, but normally this is not needed.</li>
</ul>
<hr />
<h1>Optimizing OS</h1>
<ul>
<li>No swap; If you have memory problems, add more RAM instead or configure your system to use less memory.</li>
<li>Don&#8217;t use NFS disks for data (you will have problems with NFS locking).</li>
<li>Increase number of open files for system and for the SQL server. (add <code>ulimit -n #</code> in the <code>safe_mysqld</code> script).</li>
<li>Increase the number of processes and threads for the system.</li>
<li>If you have relatively few big tables, tell your file system to not break up the file on different cylinders (Solaris).</li>
<li>Use file systems that support big files (Solaris).</li>
<li>Choose which file system to use; Reiserfs on Linux is very fast for open, read and write. File checks take just a couple of seconds.</li>
</ul>
<hr />
<h1>Choosing API</h1>
<ul>
<li>PERL
<ul>
<li>Portable programs between OS and databases</li>
<li>Good for quick prototyping</li>
<li>One should use the DBI/DBD interface</li>
</ul>
</li>
<li>PHP
<ul>
<li>Simpler to learn than PERL.</li>
<li>Uses less resources than PERL, which makes it good for embedding in Web servers.</li>
<li>One can get more speed by upgrading to PHP4.</li>
</ul>
</li>
<li>C
<ul>
<li>The native interface to MySQL.</li>
<li>Faster and gives more control</li>
<li>Lower level, so you have to work more.</li>
</ul>
</li>
<li>C++
<ul>
<li>Higher level gives you more time to code your application.</li>
<li>Is still in development.</li>
</ul>
</li>
<li>ODBC
<ul>
<li>Works on Windows and Unix</li>
<li>Almost portable between different SQL servers.</li>
<li>Slow; MyODBC, which is a simple pass-through driver is 19 % slower than using a native interface.</li>
<li>Many ways to do the same thing; Hard to get things to work as many ODBC drivers have different bugs in different areas.</li>
<li>Problematic; Microsoft changes the interface once in a while.</li>
<li>Insecure future (Microsoft pushes more for OLE than for ODBC).</li>
</ul>
</li>
<li>JDBC
<ul>
<li>In theory portable between OS and databases.</li>
<li>Can be run in the web client.</li>
</ul>
</li>
<li>Python + others
<ul>
<li>May be fine, but we don&#8217;t use them.</li>
</ul>
</li>
</ul>
<hr />
<h1>Optimizing the application</h1>
<ul>
<li>One should concentrate on solving the problem.</li>
<li>When writing the application one should decide what is most important:
<ul>
<li>Speed</li>
<li>Portability between OS</li>
<li>Portability between SQL servers</li>
</ul>
</li>
<li>Use persistent connections.</li>
<li>Cache things in your application to lessen the load of the SQL server.</li>
<li>Don&#8217;t query columns that you don&#8217;t need in your application.</li>
<li>Don&#8217;t use <code>SELECT * FROM table_name...</code></li>
<li>Benchmark all parts of your application, but put the most effort into benchmarking the whole application under the worst possible &#8216;reasonable&#8217; load. By doing this in a modular fashion you should be able to replace the found bottleneck with a fast &#8216;dummy module&#8217;, you can then easily identify the next bottleneck (and so on).</li>
<li>Use <code>LOCK TABLES</code> if you do a lot of changes in a batch; For example group multiple <code>UPDATES</code> or <code>DELETES</code> together.</li>
</ul>
<hr />
<h1>Portable applications should use</h1>
<ul>
<li>Perl DBI/DBD</li>
<li>ODBC</li>
<li>JDBC</li>
<li>Python (or any other language that has a generalized SQL interface)</li>
<li>You should only use SQL constructs which exist in all the target SQL servers or can easily be emulated with other constructs. The crash-me pages on <tt>dev.mysql.com</tt> can help you with this.</li>
<li>Write wrappers to provide missing functionality for other OSes / SQL servers.</li>
</ul>
<hr />
<h1>If you need more speed, you should:</h1>
<ul>
<li>Find the bottleneck (CPU, disk, memory, SQL server, OS, API, or application) and concentrate on solving this.</li>
<li>Use extensions that give you more speed / flexibility.</li>
<li>Get to know your SQL server so that you can use the fastest possible SQL constructs for your problem and avoid bottlenecks.</li>
<li>Optimize your table layouts and queries.</li>
<li>Use replication to get more select speed.</li>
<li>If you have a slow net connection to the database, use the compressed client/server protocol.</li>
</ul>
<p>Don&#8217;t be afraid to make the first version of your application not perfectly portable; when you have solved your problem, you can always optimize it later.</p>
<hr />
<h1>Optimizing MySQL</h1>
<ul>
<li>Choose compiler and compiler options.</li>
<li>Find the best MySQL startup options for your system.</li>
<li>Scan the the MySQL manual and read Paul DuBois&#8217; MySQL book.</li>
<li>Use <code>EXPLAIN SELECT</code>, <code>SHOW VARIABLES</code>, <code>SHOW STATUS</code> and <code>SHOW PROCESSLIST</code>.</li>
<li>Learn how the query optimizer works.</li>
<li>Optimize your table formats.</li>
<li>Maintain your tables (<code>myisamchk</code>, <code>CHECK TABLE</code>, <code>OPTIMIZE TABLE</code>).</li>
<li>Use MySQL extensions to get things done faster.</li>
<li>Write a MySQL UDF function if you notice that you would need some function in many places.</li>
<li>Don&#8217;t use <code>GRANT</code> on table level or column level if you don&#8217;t really need it.</li>
<li>Pay for MySQL support and get help to solve your problem <img src='http://ricotek.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<hr />
<h1>Compiling and installing MySQL</h1>
<ul>
<li>By choosing the best possible compiler for your system, you can usually get 10-30 % better performance.</li>
<li>On Linux/Intel, compile MySQL with pgcc. (The Pentium optimized version of gcc). The binary will only work with Intel Pentium CPUs, however.</li>
<li>Use the optimize options that are recommended in the MySQL manual for a particular platform.</li>
<li>Normally a native compiler for a specific CPU (like Sun Workshop for Sparc) should give better performance than gcc, but this is not always the case.</li>
<li>Compile MySQL with only the character sets you are going to use.</li>
<li>Compile the mysqld executable statically (with <code>--with-mysqld-ldflags=-all-static</code>) and strip the final executable with <code>strip sql/mysqld</code>.</li>
<li>Note that as MySQL doesn&#8217;t use C++ exceptions, compiling MySQL without exceptions support will give a big performance win!</li>
<li>Use native threads (instead of the included mit-pthreads) if your OS supports native threads.</li>
<li>Test the resulting binary with the MySQL benchmark test.</li>
</ul>
<hr />
<h1>Maintenance</h1>
<ul>
<li>If possible, run <code>OPTIMIZE table</code> once in a while. This is especially important on variable size rows that are updated a lot.</li>
<li>Update the key distribution statistics in your tables once in a while with <code>myisamchk -a</code>; Remember to take down MySQL before doing this!</li>
<li>If you get fragmented files, it may be worth it to copy all files to another disk, clear the old disk and copy the files back.</li>
<li>If you have problems, check your tables with myisamchk or <code>CHECK table</code>.</li>
<li>Monitor MySQL status with: <code>mysqladmin -i10 processlist extended-status</code></li>
<li>With the MySQL GUI client you can monitor the process list and the status in different windows.</li>
<li>Use <code>mysqladmin debug</code> to get information about locks and performance.</li>
</ul>
<hr />
<h1>Optimizing SQL</h1>
<p>Use SQL for the things it&#8217;s good at, and do other things in your application. Use the SQL server to:</p>
<ul>
<li>Find rows based on <code>WHERE</code> clause.</li>
<li><code>JOIN</code> tables</li>
<li><code>GROUP BY</code></li>
<li><code>ORDER BY</code></li>
<li><code>DISTINCT</code></li>
</ul>
<p>Don&#8217;t use an SQL server:</p>
<ul>
<li>To validate data (like date)</li>
<li>As a calculator</li>
</ul>
<p>Tips</p>
<ul>
<li>Use keys wisely.</li>
<li>Keys are good for searches, but bad for inserts / updates of key columns.</li>
<li>Keep by data in the 3rd normal database form, but don&#8217;t be afraid of duplicating information or creating summary tables if you need more speed.</li>
<li>Instead of doing a lot of <code>GROUP BY</code>s on a big table, create summary tables of the big table and query this instead.</li>
<li><code>UPDATE table set count=count+1 where key_column=constant</code> is very fast!</li>
<li>For log tables, it&#8217;s probably better to generate summary tables from them once in a while than try to keep the summary tables live.</li>
<li>Take advantage of default values on <code>INSERT</code>.</li>
</ul>
<hr />
<h1>Speed difference between different SQL servers (times in seconds)</h1>
<table width="80%" border="1">
<tbody>
<tr>
<td><strong>Reading 2000000 rows by key:</strong></td>
<td><strong>NT</strong></td>
<td><strong>Linux</strong></td>
</tr>
<tr>
<td>mysql</td>
<td>367</td>
<td>249</td>
</tr>
<tr>
<td>mysql_odbc</td>
<td>464</td>
<td>†</td>
</tr>
<tr>
<td>db2_odbc</td>
<td>1206</td>
<td>†</td>
</tr>
<tr>
<td>informix_odbc</td>
<td>121126</td>
<td>†</td>
</tr>
<tr>
<td>ms-sql_odbc</td>
<td>1634</td>
<td>†</td>
</tr>
<tr>
<td>oracle_odbc</td>
<td>20800</td>
<td>†</td>
</tr>
<tr>
<td>solid_odbc</td>
<td>877</td>
<td>†</td>
</tr>
<tr>
<td>sybase_odbc</td>
<td>17614</td>
<td>†</td>
</tr>
<tr>
<td colspan="3">†</td>
</tr>
<tr>
<td><strong>Inserting (350768) rows:</strong></td>
<td><strong>NT</strong></td>
<td><strong>Linux</strong></td>
</tr>
<tr>
<td>mysql</td>
<td>381</td>
<td>206</td>
</tr>
<tr>
<td>mysql_odbc</td>
<td>619</td>
<td>†</td>
</tr>
<tr>
<td>db2_odbc</td>
<td>3460</td>
<td>†</td>
</tr>
<tr>
<td>informix_odbc</td>
<td>2692</td>
<td>†</td>
</tr>
<tr>
<td>ms-sql_odbc</td>
<td>4012</td>
<td>†</td>
</tr>
<tr>
<td>oracle_odbc</td>
<td>11291</td>
<td>†</td>
</tr>
<tr>
<td>solid_odbc</td>
<td>1801</td>
<td>†</td>
</tr>
<tr>
<td>sybase_odbc</td>
<td>4802</td>
<td>†</td>
<td></td>
</tr>
</tbody>
</table>
<p>In the above test, MySQL was run with a 8M cache; the other databases were run with installations defaults.</p>
<hr />
<h1>Important MySQL startup options</h1>
<table width="80%" border="1">
<tbody>
<tr>
<td><code>back_log</code></td>
<td>Change if you do a lot of new connections.</td>
</tr>
<tr>
<td><code>thread_cache_size</code></td>
<td>Change if you do a lot of new connections.</td>
</tr>
<tr>
<td><code>key_buffer_size</code></td>
<td>Pool for index pages; Can be made very big</td>
</tr>
<tr>
<td><code>bdb_cache_size</code></td>
<td>Record and key cache used by BDB tables.</td>
</tr>
<tr>
<td><code>table_cache</code></td>
<td>Change if you have many tables or simultaneous connections</td>
</tr>
<tr>
<td><code>delay_key_write</code></td>
<td>Set if you need to buffer all key writes</td>
</tr>
<tr>
<td><code>log_slow_queries</code></td>
<td>Find queries that takes a lot of time</td>
</tr>
<tr>
<td><code>max_heap_table_size</code></td>
<td>Used with <code>GROUP BY</code></td>
</tr>
<tr>
<td><code>sort_buffer</code></td>
<td>Used with <code>ORDER BY</code> and <code>GROUP BY</code></td>
</tr>
<tr>
<td><code>myisam_sort_buffer_size</code></td>
<td>Used with <code>REPAIR TABLE</code></td>
</tr>
<tr>
<td><code>join_buffer_size</code></td>
<td>When doing a join without keys</td>
</tr>
</tbody>
</table>
<hr />
<h1>Optimizing tables</h1>
<ul>
<li>MySQL has a rich set of different types. You should try to use the most efficient type for each column.</li>
<li>The <code>ANALYSE</code> procedure can help you find the optimal types for a table: <code>SELECT * FROM table_name PROCEDURE ANALYSE()</code></li>
<li>Use <code>NOT NULL</code> for columns which will not store null values. This is particularly important for columns which you index.</li>
<li>Change your ISAM tables to MyISAM.</li>
<li>If possible, create your tables with a fixed table format.</li>
<li>Don&#8217;t create indexes you are not going to use.</li>
<li>Use the fact that MySQL can search on a prefix of an index; If you have and <code>INDEX (a,b)</code>, you don&#8217;t need an index on <code>(a)</code>.</li>
<li>Instead of creating an index on long <code>CHAR</code>/<code>VARCHAR</code> column, index just a prefix of the column to save space. <code>CREATE TABLE table_name (hostname CHAR(255) not null, index(hostname(10)))</code></li>
<li>Use the most efficient table type for each table.</li>
<li>Columns with identical information in different tables should be declared identically and have identical names.</li>
</ul>
<hr />
<h1>How MySQL stores data</h1>
<ul>
<li>Databases are stored as directories.</li>
<li>Tables are stored as files.</li>
<li>Columns are stored in the files in dynamic length or fixed size format. In BDB tables the data is stored in pages.</li>
<li>Memory-based tables are supported.</li>
<li>Databases and tables can be symbolically linked from different disks.</li>
<li>On Windows MySQL supports internal symbolic links to databases with <code>.sym</code> files.</li>
</ul>
<hr />
<h1>MySQL table types</h1>
<ul>
<li>HEAP tables; Fixed row size tables that are only stored in memory and indexed with a HASH index.</li>
<li>ISAM tables; The old B-tree table format in MySQL 3.22.</li>
<li>MyISAM tables; New version of the ISAM tables with a lot of extensions:
<ul>
<li>Binary portability.</li>
<li>Index on NULL columns.</li>
<li>Less fragmentation for dynamic-size rows than ISAM tables.</li>
<li>Support for big files.</li>
<li>Better index compression.</li>
<li>Better key statistics.</li>
<li>Better and faster auto_increment handling.</li>
</ul>
</li>
<li>Berkeley DB (BDB) tables from Sleepycat: Transaction-safe (with <code>BEGIN WORK</code> / <code>COMMIT</code> | <code>ROLLBACK</code>).</li>
</ul>
<hr />
<h1>MySQL row types (only relevant for ISAM/MyISAM tables)</h1>
<ul>
<li>MySQL will create the table in fixed size table format if all columns are of fixed length format (no <code>VARCHAR</code>, <code>BLOB</code> or <code>TEXT</code> columns). If not, the table is created in dynamic-size format.</li>
<li>Fixed-size format is much faster and more secure than the dynamic format.</li>
<li>The dynamic-size row format normally takes up less space but may be fragmented over time if the table is updated a lot.</li>
<li>In some cases it&#8217;s worth it to move all <code>VARCHAR</code>, <code>BLOB</code> and <code>TEXT</code> columns to another table just to get more speed on the main table.</li>
<li>With <code>myisampack</code> (<code>pack_isam</code> for ISAM) one can create a read-only, packed table. This minimizes disk usage which is very nice when using slow disks. The packed tables are perfect to use on log tables which one will not update anymore.</li>
</ul>
<hr />
<h1>MySQL caches (shared between all threads, allocated once)</h1>
<ul>
<li>Key cache ; key_buffer_size, default 8M</li>
<li>Table cache ; table_cache, default 64</li>
<li>Thread cache ; thread_cache_size, default 0.</li>
<li>Hostname cache ; Changeable at compile time, default 128.</li>
<li>Memory mapped tables ; Currently only used for compressed tables.</li>
</ul>
<p>Note that MySQL doesn&#8217;t have a row cache, but lets the OS handle this!</p>
<hr />
<h1>MySQL buffer variables (not shared, allocated on demand)</h1>
<ul>
<li>sort_buffer ; <code>ORDER BY</code> / <code>GROUP BY</code></li>
<li>record_buffer ; Scanning tables</li>
<li>join_buffer_size ; Joining without keys</li>
<li>myisam_sort_buffer_size ; <code>REPAIR TABLE</code></li>
<li>net_buffer_length ; For reading the SQL statement and buffering the result.</li>
<li>tmp_table_size ; HEAP-table-size for temporary results.</li>
</ul>
<hr />
<h1>How the MySQL table cache works</h1>
<ul>
<li>Each open instance of a MyISAM table uses an index file and a data file. If a table is used by two threads or used twice in the same query, MyISAM will share the index file but will open another instance of the data file.</li>
<li>The cache will temporarily grow larger than the table cache size if all tables in the cache are in use. If this happens, the next table that is released will be closed.</li>
<li>You can check if your table cache is too small by checking the mysqld variable Opened_tables. If this value is high you should increase your table cache!</li>
</ul>
<hr />
<h1>MySQL extensions / optimization that gives you speed</h1>
<ul>
<li>Use the optimal table type (HEAP, MyISAM, or BDB tables).</li>
<li>Use optimal columns for your data.</li>
<li>Use fixed row size if possible.</li>
<li>Use the different lock types (<code>SELECT HIGH_PRIORITY</code>, <code>INSERT LOW_PRIORITY</code>)</li>
<li><code>Auto_increment</code></li>
<li><code>REPLACE</code> (<code>REPLACE INTO table_name VALUES (...)</code>)</li>
<li><code>INSERT DELAYED</code></li>
<li><code>LOAD DATA INFILE</code> / <code>LOAD_FILE()</code></li>
<li>Use multi-row <code>INSERT</code> to insert many rows at a time.</li>
<li><code>SELECT INTO OUTFILE</code></li>
<li><code>LEFT JOIN</code>, <code>STRAIGHT JOIN</code></li>
<li><code>LEFT JOIN</code> combined with <code>IS NULL</code></li>
<li><code>ORDER BY</code> can use keys in some cases.</li>
<li>If you only query columns that are in one index, only the index tree will be used to resolve the query.</li>
<li>Joins are normally faster than subselects (this is true for most SQL servers).</li>
<li><code>LIMIT</code>
<ul>
<li><code>SELECT * from table1 WHERE a &gt; 10 LIMIT 10,20</code></li>
<li><code>DELETE * from table1 WHERE a &gt; 10 LIMIT 10</code></li>
</ul>
</li>
<li><code>foo IN (</code>list of constants<code>)</code> is very optimized.</li>
<li><code>GET_LOCK()</code>/<code>RELEASE_LOCK()</code></li>
<li><code>LOCK TABLES</code></li>
<li><code>INSERT</code> and <code>SELECT</code> can run concurrently.</li>
<li>UDF functions that can be loaded into a running server.</li>
<li>Compressed read-only tables.</li>
<li><code>CREATE TEMPORARY TABLE</code></li>
<li><code>CREATE TABLE .. SELECT</code></li>
<li>MyISAM tables with RAID option to split a file over many files to get over the 2G limit on some file system.</li>
<li><code>Delayed_keys</code></li>
<li>Replication</li>
</ul>
<hr />
<h1>When MySQL uses indexes</h1>
<ul>
<li>Using <code><code>&gt;, &gt;=, =, &lt;, &lt;=, IF NULL and BETWEEN on a key.<br />
</code></code></p>
<ul>
<li><code>SELECT * FROM table_name WHERE key_part1=1 and key_part2 &gt; 5;</code></li>
<li><code>SELECT * FROM table_name WHERE key_part1 IS NULL;</code></li>
</ul>
</li>
<li><code><code>When you use a LIKE that doesn't start with a wildcard.<br />
</code></code></p>
<ul>
<li><code>SELECT * FROM table_name WHERE key_part1 LIKE 'jani%'</code></li>
</ul>
</li>
<li><code><code>Retrieving rows from other tables when performing joins.<br />
</code></code></p>
<ul>
<li><code>SELECT * from t1,t2 where t1.col=t2.key_part</code></li>
</ul>
</li>
<li><code><code>Find the <code>MAX()</code> or <code>MIN()</code> value for a specific index.<br />
</code></code></p>
<ul>
<li><code>SELECT MIN(key_part2),MAX(key_part2) FROM table_name where key_part1=10</code></li>
</ul>
</li>
<li><code><code><code>ORDER BY</code> or <code>GROUP BY</code> on a prefix of a key.<br />
</code></code></p>
<ul>
<li><code>SELECT * FROM foo ORDER BY key_part1,key_part2,key_part3</code></li>
</ul>
</li>
<li><code><code>When all columns used in the query are part of one key.<br />
</code></code></p>
<ul>
<li><code>SELECT key_part3 FROM table_name WHERE key_part1=1</code></li>
</ul>
</li>
</ul>
<hr />
<h1>When MySQL doesn&#8217;t use an index</h1>
<ul>
<li>Indexes are NOT used if MySQL can calculate that it will probably be faster to scan the whole table. For example if <code>key_part1</code> is evenly distributed between 1 and 100, it&#8217;s not good to use an index in the following query:
<ul>
<li><code>SELECT * FROM table_name where key_part1 &gt; 1 and key_part1 &lt; 90</code></li>
</ul>
</li>
<li>If you are using HEAP tables and you don&#8217;t search on all key parts with =</li>
<li>When you use <code>ORDER BY</code> on a HEAP table</li>
<li>If you are not using the first key part
<ul>
<li><code>SELECT * FROM table_name WHERE key_part2=1</code></li>
</ul>
</li>
<li>If you are using <code>LIKE</code> that starts with a wildcard
<ul>
<li><code>SELECT * FROM table_name WHERE key_part1 LIKE '%jani%'</code></li>
</ul>
</li>
<li>When you search on one index and do an ORDER BY on another
<ul>
<li><code>SELECT * from table_name WHERE key_part1 = # ORDER BY key2</code></li>
</ul>
</li>
</ul>
<hr />
<h1>Learn to use EXPLAIN</h1>
<p><code><code>Use <code>EXPLAIN</code> on every query that you think is too slow!</code></code></p>
<pre>mysql&gt; explain select t3.DateOfAction, t1.TransactionID
    -&gt; from t1 join t2 join t3
    -&gt; where t2.ID = t1.TransactionID and t3.ID = t2.GroupID
    -&gt; order by t3.DateOfAction, t1.TransactionID;
+-------+--------+---------------+---------+---------+------------------+------+---------------------------------+
| table | type   | possible_keys | key     | key_len | ref              | rows | Extra                           |
+-------+--------+---------------+---------+---------+------------------+------+---------------------------------+
| t1    | ALL    | NULL          | NULL    |    NULL | NULL             |   11 | Using temporary; Using filesort |
| t2    | ref    | ID            | ID      |       4 | t1.TransactionID |   13 |                                 |
| t3    | eq_ref | PRIMARY       | PRIMARY |       4 | t2.GroupID       |    1 |                                 |
+-------+--------+---------------+---------+---------+------------------+------+---------------------------------+</pre>
<p><code><code>Types <code>ALL</code> and <code>range</code> signal a potential problem.</code></code></p>
<hr />
<h1>Learn to use SHOW PROCESSLIST</h1>
<p><code><code>Use <code>SHOW processlist</code> to find out what is going on:</code></code></p>
<pre>+----+-------+-----------+----+---------+------+--------------+-------------------------------------+
| Id | User  | Host      | db | Command | Time | State        | Info                                |
+----+-------+-----------+----+---------+------+--------------+-------------------------------------+
| 6  | monty | localhost | bp | Query   | 15   | Sending data | select * from station,station as s1 |
| 8  | monty | localhost |    | Query   | 0    |              | show processlist                    |
+----+-------+-----------+----+---------+------+--------------+-------------------------------------+</pre>
<p><code><code>Use <code>KILL</code> in <code>mysql</code> or <code>mysqladmin</code> to kill off runaway threads.</code></code></p>
<hr />
<h1>How to find out how MySQL solves a query</h1>
<p><code><code>Run the following commands and try to understand the output:</code></code></p>
<ul>
<li><code>SHOW VARIABLES;</code></li>
<li><code>SHOW COLUMNS FROM ...\G</code></li>
<li><code>EXPLAIN SELECT ...\G</code></li>
<li><code>FLUSH STATUS;</code></li>
<li><code>SELECT ...;</code></li>
<li><code>SHOW STATUS;</code></li>
</ul>
<hr />
<h1>MySQL is extremely good</h1>
<ul>
<li>For logging.</li>
<li>When you do many connects; connect is very fast.</li>
<li>Where you use <code>SELECT</code> and <code>INSERT</code> at the same time.</li>
<li>When you don&#8217;t combine updates with selects that take a long time.</li>
<li>When most selects/updates are using unique keys.</li>
<li>When you use many tables without long conflicting locks.</li>
<li>When you have big tables (MySQL uses a very compact table format).</li>
</ul>
<hr />
<h1>Things to avoid with MySQL</h1>
<ul>
<li>Updates to a table or <code>INSERT</code> on a table with deleted rows, combined with <code>SELECTS</code> that take a long time.</li>
<li><code>HAVING</code> on things you can have in a <code>WHERE</code> clause.</li>
<li><code>JOINS</code> without using keys or keys which are not unique enough.</li>
<li><code>JOINS</code> on columns that have different column types.</li>
<li>Using HEAP tables when not using a full key match with <code>=</code></li>
<li>Forgetting a <code>WHERE</code> clause with <code>UPDATE</code> or <code>DELETE</code> in the MySQL monitor. If you tend to do this, use the <code>--i-am-a-dummy</code> option to the <code>mysq</code> client.</li>
</ul>
<hr />
<h1>Different locks in MySQL</h1>
<ul>
<li>Internal table locks.</li>
<li><code>LOCK TABLES</code> (Works on all table types)</li>
<li><code>GET_LOCK()</code>/<code>RELEASE_LOCK()</code></li>
<li>Page locks (for BDB tables)</li>
<li><code>ALTER TABLE</code> also does a table lock on BDB tables.</li>
<li><code>LOCK TABLES</code> gives you multiple readers on a table or one writer.</li>
<li>Normally a <code>WRITE</code> lock has higher priority than a <code>READ</code> lock to avoid starving the writers. For writers that are not important one can use the<code>LOW_PRIORITY</code> keyword to let the lock handler prefer readers.
<pre>  UPDATE LOW_PRIORITY SET value=10 WHERE id=10;</pre>
</li>
</ul>
<hr />
<h1>Tricks to give MySQL more information to solve things better</h1>
<p><code><code>Note that you can always comment out a MySQL feature to make the query portable:</code></code></p>
<pre>SELECT /*! SQL_BUFFER_RESULTS */ ...</pre>
<ul>
<li><code>SELECT SQL_BUFFER_RESULTS ...</code><br />
Will force MySQL to make a temporary result set. As soon as the temporary set is done, all locks on the tables are released. This can help when you get a problem with table locks or when it takes a long time to transfer the result to the client.</li>
<li><code>SELECT SQL_SMALL_RESULT ... GROUP BY ...</code><br />
To tell the optimizer that the result set will only contain a few rows.</li>
<li><code>SELECT SQL_BIG_RESULT ... GROUP BY ...</code><br />
To tell the optimizer that the result set will contain many rows.</li>
<li><code>SELECT STRAIGHT_JOIN ...</code><br />
Forces the optimizer to join the tables in the order in which they are listed in the <code>FROM</code> clause.</li>
<li><code>SELECT ... FROM table_name [USE INDEX (index_list) | IGNORE INDEX (index_list)] table_name2</code><br />
Forces MySQL to use/ignore the listed indexes.</li>
</ul>
<hr />
<h1>Example of doing transactions</h1>
<ul>
<li>How to do a transaction with MyISAM tables:
<pre>mysql&gt; LOCK TABLES trans READ, customer WRITE;
mysql&gt; select sum(value) from trans where customer_id=some_id;
mysql&gt; update customer set total_value=sum_from_previous_statement
           where customer_id=some_id;
mysql&gt; UNLOCK TABLES;</pre>
</li>
<li>How to do a transaction with Berkeley DB tables:
<pre>mysql&gt; BEGIN WORK; 
mysql&gt; select sum(value) from trans where customer_id=some_id;
mysql&gt; update customer set total_value=sum_from_previous_statement
           where customer_id=some_id;
mysql&gt; COMMIT;</pre>
</li>
<li>Note that you can often avoid transactions altogether by doing:
<pre>UPDATE customer SET value=value+new_value WHERE customer_id=some_id;</pre>
</li>
</ul>
<hr />
<h1>Example of using REPLACE</h1>
<p><code><code><code>REPLACE</code> works exactly like <code>INSERT</code>, except that if an old record in the table has the same value as a new record on a unique index, the old record is deleted before the new record is inserted. Instead of using</code></code></p>
<pre>  SELECT 1 FROM t1 WHERE key=#
  IF found-row
    LOCK TABLES t1
    DELETE FROM t1 WHERE key1=#
    INSERT INTO t1 VALUES (...)
    UNLOCK TABLES t1;
  ENDIF</pre>
<p><code><code>Do</code></code></p>
<pre>  REPLACE INTO t1 VALUES (...)</pre>
<hr />
<h1>General tips</h1>
<ul>
<li>Use short primary keys. Use numbers, not strings, when joining tables.</li>
<li>When using multi-part keys, the first part should be the most-used key.</li>
<li>When in doubt, use columns with more duplicates first to get better key compression.</li>
<li>If you run the client and MySQL server on the same machine, use sockets instead of TCP/IP when connecting to MySQL (this can give you up to a 7.5 % improvement). You can do this by specifying no hostname or <code>localhost</code> when connecting to the MySQL server.</li>
<li>Use <code>--skip-locking</code> (default on some OSes) if possible. This will turn off external locking and will give better performance.</li>
<li>Use application-level hashed values instead of using long keys:
<pre>  SELECT * FROM table_name WHERE hash=MD5(concat(col1,col2)) AND
  col_1='constant' AND col_2='constant'</pre>
</li>
<li>Store BLOB&#8217;s that you need to access as files in files. Store only the file name in the database.</li>
<li>It is faster to remove all rows than to remove a large part of the rows.</li>
<li>If SQL is not fast enough, take a look at the lower level interfaces to access the data.</li>
</ul>
<hr />
<h1>Benefits of using MySQL 3.23</h1>
<ul>
<li>MyISAM ; Portable BIG table format</li>
<li>HEAP ; In memory tables</li>
<li>Berkeley DB ; Transactional tables from Sleepycat.</li>
<li>A lot of raised limits</li>
<li>Dynamic character sets</li>
<li>More <code>STATUS</code> variables.</li>
<li><code>CHECK</code> and <code>REPAIR</code> table.</li>
<li>Faster <code>GROUP BY</code> and <code>DISTINCT</code></li>
<li><code>LEFT JOIN ... IF NULL</code> optimization.</li>
<li><code>CREATE TABLE ... SELECT</code></li>
<li><code>CREATE TEMPORARY table_name (...)</code></li>
<li>Automatic conversion of temporary HEAP to MyISAM tables</li>
<li>Replication</li>
<li>mysqlhotcopy script.</li>
</ul>
<hr />
<h1>Important features that we are actively working on</h1>
<ul>
<li>Improving transactions</li>
<li>Fail safe replication</li>
<li>Text searching</li>
<li>Delete with many tables (Updates with many tables will be done after this.)</li>
<li>Better key cache</li>
<li>Atomic <code>RENAME</code> (<code>RENAME TABLE foo as foo_old, foo_new as foo</code>)</li>
<li>A query cache</li>
<li><code>MERGE TABLES</code></li>
<li>A better GUI client</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://ricotek.net/uncategorized/optimize-mysql/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iostat, vmstat and mpstat</title>
		<link>http://ricotek.net/uncategorized/iostat-vmstat-and-mpstat?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=iostat-vmstat-and-mpstat</link>
		<comments>http://ricotek.net/uncategorized/iostat-vmstat-and-mpstat#comments</comments>
		<pubDate>Sat, 18 Feb 2012 18:59:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://ricotek.net/?p=915</guid>
		<description><![CDATA[24 iostat, vmstat and mpstat Examples for Linux Performance Monitoring This article provides a total of 24 examples on iostat, vmstat, and mpstat commands. iostat reports CPU, disk I/O, and NFS statistics. vmstat reports virtual memory statistics. mpstat reports processors statictics. This article is part of our ongoing Linux performance … <a href="http://ricotek.net/uncategorized/iostat-vmstat-and-mpstat"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<div>
<h1>24 iostat, vmstat and mpstat Examples for Linux Performance Monitoring</h1>
</div>
<div>
<p>This article provides a total of 24 examples on iostat, vmstat, and mpstat commands.</p>
<ul>
<li>iostat reports CPU, disk I/O, and NFS statistics.</li>
<li>vmstat reports virtual memory statistics.</li>
<li>mpstat reports processors statictics.</li>
</ul>
<p>This article is part of our ongoing Linux performance monitoring series.</p>
<p>Please note that iostat and vmstat are part of the sar utility. You should install sysstat package as explained in our <a href="http://www.thegeekstuff.com/2011/03/sar-examples/">sar</a> (sysstat) article to get iostat and vmstat working.</p>
<h2>IOSTAT EXAMPLES</h2>
<h3>1. iostat – Basic example</h3>
<p>Iostat without any argument displays information about the CPU usage, and I/O statistics about all the partitions on the system as shown below.</p>
<pre>$ iostat
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.68    0.00    0.52    2.03    0.00   91.76

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda             194.72      1096.66      1598.70 2719068704 3963827344
sda1            178.20       773.45      1329.09 1917686794 3295354888
sda2             16.51       323.19       269.61  801326686  668472456
sdb             371.31       945.97      1073.33 2345452365 2661206408
sdb1            371.31       945.95      1073.33 2345396901 2661206408
sdc             408.03       207.05       972.42  513364213 2411023092
sdc1            408.03       207.03       972.42  513308749 2411023092</pre>
<h3>2. iostat – Display only cpu statistics</h3>
<p>iostat option -c, displays only the CPU usage statistics as shown below.</p>
<pre>$ iostat -c
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.68    0.00    0.52    2.03    0.00   91.76</pre>
<h3>3. iostat – Display only disk I/O statistics</h3>
<p>iostat option -d, displays only the disk I/O statistics as shown below.</p>
<pre>$ iostat -d
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda             194.71      1096.61      1598.63 2719068720 3963827704
sda1            178.20       773.41      1329.03 1917686810 3295355248
sda2             16.51       323.18       269.60  801326686  668472456
sdb             371.29       945.93      1073.28 2345452365 2661209192
sdb1            371.29       945.91      1073.28 2345396901 2661209192
sdc             408.01       207.04       972.38  513364213 2411024484
sdc1            408.01       207.02       972.38  513308749 2411024484</pre>
<h3>4. iostat – Display only network statistics</h3>
<p>iostat option -n, displays only the device and NFS statistics as shown below.</p>
<p>&nbsp;</p>
<div><ins><ins id="aswift_2_anchor"><iframe id="aswift_2" name="aswift_2" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="336" height="280"></iframe></ins></ins></div>
<p>&nbsp;</p>
<pre>$ iostat -n
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)        07/09/2011

avg-cpu:  %user   %nice    %sys %iowait   %idle
           4.33    0.01    1.16    0.31   94.19

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda               2.83         0.35         5.39   29817402  457360056
sda1              3.32        50.18         4.57 4259963994  387641400
sda2              0.20         0.76         0.82   64685128   69718576
sdb               6.59        15.53        42.98 1318931178 3649084113
sdb1             11.80        15.53        42.98 1318713382 3649012985

Device:                  rBlk_nor/s   wBlk_nor/s   rBlk_dir/s   wBlk_dir/s   rBlk_svr/s   wBlk_svr/s
192.168.1.4:/home/data      90.67        0.00         0.00         0.00         5.33         0.00
192.168.1.4:/backup         8.74         0.00         0.00         0.00         8.74         0.00
192.168.1.8:/media          0.02         0.00         0.00         0.00         0.01         0.00</pre>
<h3>5. iostat – Display I/O data in MB/second</h3>
<p>By default iostat, displays the device I/O statistics in Blocks. To change it to MB, use -m as shown below.</p>
<pre>$ iostat -m
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.68    0.00    0.52    2.03    0.00   91.76

Device:            tps    MB_read/s    MB_wrtn/s    MB_read    MB_wrtn
sda             194.70         0.54         0.78    1327670    1935463
sda1            178.19         0.38         0.65     936370    1609060
sda2             16.51         0.16         0.13     391272     326402
sdb             371.27         0.46         0.52    1145240    1299425
sdb1            371.27         0.46         0.52    1145213    1299425
sdc             407.99         0.10         0.47     250666    1177259
sdc1            407.99         0.10         0.47     250639    1177259</pre>
<h3>6. iostat – Display I/O statistics only for a device</h3>
<p>By default iostat displays I/O data for all the disks available in the system. To view statistics for a specific device (For example, /dev/sda), use the option -p as shown below.</p>
<pre>$ iostat -p sda
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.68    0.00    0.52    2.03    0.00   91.76

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda             194.69      1096.51      1598.48 2719069928 3963829584
sda2            336.38        27.17        54.00   67365064  133905080
sda1            821.89         0.69       243.53    1720833  603892838</pre>
<h3>7. iostat – Display timestamp information</h3>
<p>By default iostat displays only the current date. To display the current time, use the option -t as shown below.</p>
<pre>$ iostat -t
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011

Time: 08:57:52 AM
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.68    0.00    0.52    2.03    0.00   91.76

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda             194.69      1096.49      1598.45 2719070384 3963829704
sda1            178.18       773.32      1328.88 1917688474 3295357248
sda2             16.51       323.14       269.57  801326686  668472456
sdb             371.25       945.82      1073.16 2345452741 2661228872
sdb1            371.25       945.80      1073.16 2345397277 2661228872
sdc             407.97       207.02       972.27  513364233 2411030200
sdc1            407.97       207.00       972.27  513308769 2411030200</pre>
<h3>8. iostat – Display Extended status</h3>
<p>Use option -x, which will displays extended disk I/O statistics information as shown below.</p>
<pre>$ iostat -x
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.68    0.00    0.52    2.03    0.00   91.76

Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda              27.86    63.53 61.77 132.91  1096.46  1598.40    13.84     0.21    1.06   2.28  44.45
sda1              0.69    33.22 48.54 129.63   773.30  1328.84    11.80     1.39    7.82   2.28  40.57
sda2             27.16    30.32 13.23  3.28   323.13   269.56    35.90     0.55   32.96   3.44   5.68
sdb              39.15   215.16 202.20 169.04   945.80  1073.13     5.44     1.05    2.78   1.64  60.91
sdb1             39.15   215.16 202.20 169.04   945.77  1073.13     5.44     1.05    2.78   1.64  60.91
sdc               8.90     3.63 356.56 51.40   207.01   972.24     2.89     1.04    2.56   1.55  63.30
sdc1              8.90     3.63 356.55 51.40   206.99   972.24     2.89     1.04    2.56   1.55  63.30</pre>
<p>To display extended information for a specific partition (For example, /dev/sda1), do the following.</p>
<pre>$ iostat -x sda1
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.68    0.00    0.52    2.03    0.00   91.76

Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda1              0.69    33.21 48.54 129.62   773.23  1328.76    11.80     1.39    7.82   2.28  40.56</pre>
<h3>9. iostat – Execute Every x seconds (for y number of times)</h3>
<p>To execute iostat every 2 seconds (until you press Ctl-C), do the following.</p>
<pre>$ iostat 2
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.68    0.00    0.52    2.03    0.00   91.76

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda             194.67      1096.39      1598.33 2719070584 3963891256
sda1            178.16       773.26      1328.79 1917688482 3295418672
sda2             16.51       323.11       269.54  801326878  668472584
sdb             371.22       945.74      1073.08 2345454041 2661251200
sdb1            371.22       945.72      1073.08 2345398577 2661251200
sdc             407.93       207.00       972.19  513366813 2411036564
sdc1            407.93       206.98       972.19  513311349 2411036564
..</pre>
<p>To execute every 2 seconds for a total of 3 times, do the following.</p>
<pre>$ iostat 2 3</pre>
<h3>10. iostat – Display LVM statistic (and version)</h3>
<p>To display the LVM statistics use option -N as shown below.</p>
<pre>$ iostat -N</pre>
<p>To display the version of iostat, use -V. This will really display the version information of sysstat, as iostat is part of sysstat package.</p>
<pre>$ iostat -V
sysstat version 7.0.2
(C) Sebastien Godard</pre>
<h2>VMSTAT EXAMPLES</h2>
<h3>11. vmstat – Basic example</h3>
<p>vmstat by default will display the memory usage (including swap) as shown below.</p>
<pre>$ vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0 305416 260688  29160 2356920    2    2     4     1    0    0  6  1 92  2  0</pre>
<p>vmstat output contains the following fields:</p>
<ul>
<li>Procs – r: Total number of processes waiting to run</li>
<li>Procs – b: Total number of busy processes</li>
<li>Memory – swpd: Used virtual memory</li>
<li>Memory – free: Free virtual memory</li>
<li>Memory – buff: Memory used as buffers</li>
<li>Memory – cache: Memory used as cache.</li>
<li>Swap – si: Memory swapped from disk (for every second)</li>
<li>Swap – so: Memory swapped to disk (for every second)</li>
<li>IO – bi: Blocks in. i.e blocks received from device (for every second)</li>
<li>IO – bo: Blocks out. i.e blocks sent to the device (for every second)</li>
<li>System – in: Interrupts per second</li>
<li>System – cs: Context switches</li>
<li>CPU – us, sy, id, wa, st: CPU user time, system time, idle time, wait time</li>
</ul>
<h3>12. vmstat – Display active and inactive memory</h3>
<p>By default vmstat doesn’t display this information. Use option -a, to display active and inactive memory information as shown below.</p>
<pre>$ vmstat -a
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
 0  0 305416 253820 1052680 2688928    2    2     4     1    0    0  6  1 92  2  0</pre>
<h3>13. vmstat – Display number of forks since last boot</h3>
<p>This displays all the fork system calls made by the system since the last boot. This displays all fork, vfork, and clone system call counts.</p>
<pre>$ vmstat -f
     81651975 forks</pre>
<h3>14. vmstat – Execute Every x seconds (for y number of times)</h3>
<p>To execute every 2 seconds, do the following. You have to press Ctrl-C to stop this.</p>
<pre>$ vmstat 2
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 537144 182736 6789320    0    0     0     0    1    1  0  0 100  0  0
 0  0      0 537004 182736 6789320    0    0     0     0   50   32  0  0 100  0  0
..</pre>
<p>To execute every 2 seconds for 10 times, do the following. You don’t need to press Ctrl-C in this case. After executing 10 times, it will stop automatically.</p>
<pre>$ vmstat 2 10
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 537144 182736 6789320    0    0     0     0    1    1  0  0 100  0  0
 0  0      0 537004 182736 6789320    0    0     0     0   50   32  0  0 100  0  0
..</pre>
<h3>15. vmstat – Display timestamp</h3>
<p>When you use vmstat to monitor the memory usage repeately, it would be nice to see the timestap along with every line item. Use option -t to display the time stamp as shown below.</p>
<pre>$ vmstat -t 1 100
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ ---timestamp---
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 3608728 148368 3898200    0    0     0     0    1    1  0  0 100  0  0     2011-07-09 21:16:28 PDT
 0  0      0 3608728 148368 3898200    0    0     0     0   60   15  0  0 100  0  0     2011-07-09 21:16:29 PDT
 0  0      0 3608712 148368 3898200    0    0     0     0   32   28  0  0 100  0  0     2011-07-09 21:16:30 PDT</pre>
<p>For me, the timestamp option worked in the following version.</p>
<pre>$ vmstat -V
procps version 3.2.8</pre>
<p><strong>Note:</strong> If you use a older version of vmstat, option -t might not be available. In that case, use the method we suggested earlier to <a href="http://www.thegeekstuff.com/2009/08/how-to-add-timestamp-to-unix-vmstat-command-output/">display timestamp in vmstat</a> output.</p>
<h3>16. vmstat – Display slab info</h3>
<p>Use option -m, to display the slab info as shown below.</p>
<pre>$ vmstat -m
Cache                       Num  Total   Size  Pages
fib6_nodes                    5    113     32    113
ip6_dst_cache                 4     15    256     15
ndisc_cache                   1     15    256     15
RAWv6                         7     10    768      5
UDPv6                         0      0    640      6
tw_sock_TCPv6                 0      0    128     30
...</pre>
<h3>17. vmstat – Display statistics in a table format</h3>
<p>Instead of displays the values in the record format, you can display the output of vmstat in table format using option -s as shown below.</p>
<pre>$ vmstat -s
      4149928  total memory
      3864824  used memory
      2606664  active memory
      1098180  inactive memory
       285104  free memory
        19264  buffer memory
      2326692  swap cache
      4192956  total swap
       274872  used swap
      3918084  free swap
   1032454000 non-nice user cpu ticks
        14568 nice user cpu ticks
     89482270 system cpu ticks
  16674327143 idle cpu ticks
    368965706 IO-wait cpu ticks
      1180468 IRQ cpu ticks
..</pre>
<h3>18. vmstat – Display disk statistics</h3>
<p>Use option -d to display the disk statistics as shown below. This displays the reads, writes, and I/O statistics of the disk.</p>
<pre>$ vmstat -d
disk- ------------reads------------ ------------writes----------- -----IO------
       total merged sectors      ms  total merged sectors      ms    cur    sec
sda   153189971 69093708 2719150864 737822879 329617713 157559204 3965687592 4068577985      0 1102243
sdb   501426305 97099356 2345472425 731613156 419220973 533565961 2661869460 1825174087      0 1510434
sdc   884213459 22078974 513390701 452540172 127474901 8993357 2411187300 2133226954      0 1569758</pre>
<h3>19. vmstat – Increase the width of the display</h3>
<p>The default output without increasing the width is shown below.</p>
<pre>$ vmstat 1 3
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 3608688 148368 3898204    0    0     0     0    1    1  0  0 100  0  0
 0  0      0 3608804 148368 3898204    0    0     0     0   72   30  0  0 100  0  0
 0  0      0 3608804 148368 3898204    0    0     0     0   60   27  0  0 100  0  0</pre>
<p>Use option -w to increase the width of the output columns as shown below. This give better readability.</p>
<pre>$ vmstat -w 1 3
procs -------------------memory------------------ ---swap-- -----io---- --system-- -----cpu-------
 r  b       swpd       free       buff      cache   si   so    bi    bo   in   cs  us sy  id wa st
 0  0          0    3608712     148368    3898204    0    0     0     0    1    1   0  0 100  0  0
 0  0          0    3608712     148368    3898204    0    0     0     0   93   23   0  0 100  0  0
 0  0          0    3608696     148368    3898204    0    0     0     0   35   34   0  0 100  0  0</pre>
<h3>20. vmstat – Display statistics for a partition</h3>
<p>To display the disk I/O statistics of a specific disk partition use option -p as shown below.</p>
<pre>$ vmstat -p sdb1
sdb1          reads   read sectors  writes    requested writes
           501423248 2345417917  419221612 2661885948</pre>
<h3>21. vmstat – Display in MB</h3>
<p>By default vmstat displays the memory information in kb. To disply in MB, use the option “-S m” as shown below.</p>
<pre>$ vmstat -S m
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0    281    288     19   2386    0    0     4     1    0    0  6  1 92  2  0</pre>
<h2>MPSTAT EXAMPLES</h2>
<h3>22. mpstat – Display basic info</h3>
<p>By default mpstat displays CPU statistics as shown below.</p>
<pre>$ mpstat
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011

10:25:32 PM  CPU   %user   %nice    %sys %iowait    %irq   %soft  %steal   %idle    intr/s
10:25:32 PM  all    5.68    0.00    0.49    2.03    0.01    0.02    0.00   91.77    146.55</pre>
<h3>23. mpstat – Display all information</h3>
<p>Option -A, displays all the information that can be displayed by the mpstat command as shown below. This is really equalivalent to “mpstat -I ALL -u -P ALL” command.</p>
<pre>$ mpstat -A
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011      _x86_64_        (4 CPU)

10:26:34 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
10:26:34 PM  all    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.99
10:26:34 PM    0    0.01    0.00    0.01    0.01    0.00    0.00    0.00    0.00   99.98
10:26:34 PM    1    0.00    0.00    0.01    0.00    0.00    0.00    0.00    0.00   99.98
10:26:34 PM    2    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
10:26:34 PM    3    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00

10:26:34 PM  CPU    intr/s
10:26:34 PM  all     36.51
10:26:34 PM    0      0.00
10:26:34 PM    1      0.00
10:26:34 PM    2      0.04
10:26:34 PM    3      0.00

10:26:34 PM  CPU     0/s     1/s     8/s     9/s    12/s    14/s    15/s    16/s    19/s    20/s    21/s    33/s   NMI/s   LOC/s   SPU/s   PMI/s   PND/s   RES/s   CAL/s   TLB/s   TRM/s   THR/s   MCE/s   MCP/s   ERR/s   MIS/s
10:26:34 PM    0    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    7.47    0.00    0.00    0.00    0.00    0.02    0.00    0.00    0.00    0.00    0.00    0.00    0.00
10:26:34 PM    1    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    4.90    0.00    0.00    0.00    0.00    0.03    0.00    0.00    0.00    0.00    0.00    0.00    0.00
10:26:34 PM    2    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.04    0.00    0.00    0.00    0.00    0.00    3.32    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
10:26:34 PM    3    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    4.17    0.00    0.00    0.00    0.00    0.01    0.00    0.00    0.00    0.00    0.00    0.00    0.00</pre>
<h3>24. mpstat – Display CPU statistics of individual CPU (or) Core</h3>
<p>Option -P ALL, displays all the individual CPUs (or Cores) along with its statistics as shown below.</p>
<pre>$ mpstat -P ALL
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011      _x86_64_        (4 CPU)

10:28:04 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
10:28:04 PM  all    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.99
10:28:04 PM    0    0.01    0.00    0.01    0.01    0.00    0.00    0.00    0.00   99.98
10:28:04 PM    1    0.00    0.00    0.01    0.00    0.00    0.00    0.00    0.00   99.98
10:28:04 PM    2    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
10:28:04 PM    3    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00</pre>
<p>To display statistics information of a particular CPU (or core), use option -P as shown below.</p>
<pre>$ mpstat -P 0
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011      _x86_64_        (8 CPU)

10:28:53 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
10:28:53 PM    0    0.01    0.00    0.01    0.01    0.00    0.00    0.00    0.00   99.98

$ mpstat -P 1
Linux 2.6.32-100.28.5.el6.x86_64 (dev-db)       07/09/2011      _x86_64_        (8 CPU)

10:28:55 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
10:28:55 PM    1    0.00    0.00    0.01    0.00    0.00    0.00    0.00    0.00   99.98</pre>
<p>Finally, as we mentioned earlier mpstat is part of the sysstat package. When you do mpstat -V, it will really display the version number of the systat package as shown below.</p>
<pre>$ mpstat -V
sysstat version 9.0.4
(C) Sebastien Godard (sysstat  orange.fr)</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://ricotek.net/uncategorized/iostat-vmstat-and-mpstat/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The MySQL Benchmark Suite</title>
		<link>http://ricotek.net/uncategorized/the-mysql-benchmark-suite?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-mysql-benchmark-suite</link>
		<comments>http://ricotek.net/uncategorized/the-mysql-benchmark-suite#comments</comments>
		<pubDate>Sat, 18 Feb 2012 18:46:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://ricotek.net/?p=922</guid>
		<description><![CDATA[This benchmark suite is meant to tell any user what operations a given SQL implementation performs well or poorly. You can get a good idea for how the benchmarks work by looking at the code and results in the sql-bench directory in any MySQL source distribution. Note that this benchmark is single-threaded, … <a href="http://ricotek.net/uncategorized/the-mysql-benchmark-suite"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>This benchmark suite is meant to tell any user what operations a given SQL implementation performs well or poorly. You can get a good idea for how the benchmarks work by looking at the code and results in the <code>sql-bench</code> directory in any MySQL source distribution.</p>
<p>Note that this benchmark is single-threaded, so it measures the minimum time for the operations performed. We plan to add multi-threaded tests to the benchmark suite in the future.</p>
<p>To use the benchmark suite, the following requirements must be satisfied:</p>
<div>
<ul>
<li>The benchmark suite is provided with MySQL source distributions. You can either download a released distribution from <a href="http://dev.mysql.com/downloads/" target="_top">http://dev.mysql.com/downloads/</a>, or use the current development source tree. (See<a title="2.17.2. Installing MySQL from a Development Source Tree" href="http://dev.mysql.com/doc/refman/5.0/en/installing-development-tree.html">Section 2.17.2, “Installing MySQL from a Development Source Tree”</a>.)</li>
<li>The benchmark scripts are written in Perl and use the Perl DBI module to access database servers, so DBI must be installed. You also need the server-specific DBD drivers for each of the servers you want to test. For example, to test MySQL, PostgreSQL, and DB2, you must have the <code>DBD::mysql</code>, <code>DBD::Pg</code>, and <code>DBD::DB2</code> modules installed. See <a title="2.22. Perl Installation Notes" href="http://dev.mysql.com/doc/refman/5.0/en/perl-support.html">Section 2.22, “Perl Installation Notes”</a>.</li>
</ul>
</div>
<p>After you obtain a MySQL source distribution, you can find the benchmark suite located in its <code>sql-bench</code>directory. To run the benchmark tests, build MySQL, and then change location into the <code>sql-bench</code> directory and execute the <code>run-all-tests</code> script:</p>
<pre>shell&gt; <strong><code>cd sql-bench</code></strong>
shell&gt; <strong><code>perl run-all-tests --server=<em><code>server_name</code></em></code></strong></pre>
<p><em><code>server_name</code></em> should be the name of one of the supported servers. To get a list of all options and supported servers, invoke this command:</p>
<pre>shell&gt; <strong><code>perl run-all-tests --help</code></strong></pre>
<p><a name="id765128"></a></p>
<p>The <strong>crash-me</strong> script also is located in the <code>sql-bench</code> directory. <strong>crash-me</strong> tries to determine what features a database system supports and what its capabilities and limitations are by actually running queries. For example, it determines:</p>
<div>
<ul>
<li>What data types are supported</li>
<li>How many indexes are supported</li>
<li>What functions are supported</li>
<li>How big a query can be</li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://ricotek.net/uncategorized/the-mysql-benchmark-suite/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Top10SQLPerformanceTips</title>
		<link>http://ricotek.net/uncategorized/top10sqlperformancetips?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=top10sqlperformancetips</link>
		<comments>http://ricotek.net/uncategorized/top10sqlperformancetips#comments</comments>
		<pubDate>Sat, 18 Feb 2012 18:38:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://ricotek.net/?p=919</guid>
		<description><![CDATA[Specific Query Performance Tips (see also database design tips for tips on indexes):Interactive session from MySQL Camp I: Use EXPLAIN to profile the query execution plan Use Slow Query Log (always have it on!) Don&#8217;t use DISTINCT when you have or could use GROUP BY Insert performance Batch INSERT and REPLACE Use … <a href="http://ricotek.net/uncategorized/top10sqlperformancetips"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<div id="container">
<div id="centered">
<div id="article">
<div>
<h1><span class="Apple-style-span" style="font-size: 16px; color: #444444; line-height: 24px;">Specific Query Performance Tips (see also database design tips for tips on indexes):</span><span class="Apple-style-span" style="font-size: 12px; line-height: 18px; color: #444444;"><a name="Top_1000_SQL_Performance_Tips"><span class="Apple-style-span" style="font-size: 16px; line-height: 24px;"><em>Interactive session from MySQL Camp I:</em></span></a></span></h1>
<ol>
<li>Use EXPLAIN to profile the query execution plan</li>
<li>Use <a title="http://dev.mysql.com/doc/refman/5.0/en/slow-query-log.html" href="http://dev.mysql.com/doc/refman/5.0/en/slow-query-log.html" rel="nofollow">Slow Query Log</a> (always have it on!)</li>
<li>Don&#8217;t use DISTINCT when you have or could use GROUP BY</li>
<li>Insert performance
<ol>
<li>Batch INSERT and REPLACE</li>
<li>Use LOAD DATA instead of INSERT</li>
</ol>
</li>
<li>LIMIT m,n may not be as fast as it sounds. <a title="http://www.facebook.com/note.php?note_id=206034210932" href="http://www.facebook.com/note.php?note_id=206034210932" rel="nofollow">Learn how to improve it</a> and read more about <a title="http://www.xarg.org/2011/10/optimized-pagination-using-mysql/" href="http://www.xarg.org/2011/10/optimized-pagination-using-mysql/" rel="nofollow">Efficient Pagination Using MySQL</a></li>
<li>Don&#8217;t use ORDER BY RAND() if you have &gt; ~2K records</li>
<li>Use SQL_NO_CACHE when you are SELECTing frequently updated data or large sets of data</li>
<li>Avoid wildcards at the start of LIKE queries</li>
<li>Avoid correlated subqueries and in select and where clause (try to avoid in)</li>
<li>No calculated comparisons &#8212; isolate indexed columns</li>
<li>ORDER BY and LIMIT work best with equalities and covered indexes</li>
<li>Separate text/blobs from metadata, don&#8217;t put text/blobs in results if you don&#8217;t need them</li>
<li>Derived tables (subqueries in the FROM clause) can be useful for retrieving BLOBs without sorting them. (Self-join can speed up a query if 1st part finds the IDs and uses then to fetch the rest)</li>
<li>ALTER TABLE&#8230;ORDER BY can take data sorted chronologically and re-order it by a different field &#8212; this can make queries on that field run faster (maybe this goes in indexing?)</li>
<li>Know when to split a complex query and join smaller ones</li>
<li>Delete small amounts at a time if you can</li>
<li>Make similar queries consistent so cache is used</li>
<li>Have good SQL query standards</li>
<li>Don&#8217;t use deprecated features</li>
<li>Turning OR on multiple index fields (&lt;5.0) into UNION may speed things up (with LIMIT), after 5.0 the index_merge should pick stuff up.</li>
<li>Don&#8217;t use COUNT * on Innodb tables for every search, do it a few times and/or summary tables, or if you need it for the total # of rows, use SQL_CALC_FOUND_ROWS and SELECT FOUND_ROWS()</li>
<li>Use INSERT &#8230; ON DUPLICATE KEY update (INSERT IGNORE) to avoid having to SELECT</li>
<li>use groupwise maximum instead of subqueries</li>
<li>Avoid using IN(&#8230;) when selecting on indexed fields, It will kill the performance of SELECT query.</li>
<li>Prefer using UNION ALL if you don&#8217;t need to merge the result</li>
</ol>
<p>Scaling Performance Tips:</p>
<ol>
<li>Use benchmarking</li>
<li>isolate workloads don&#8217;t let administrative work interfere with customer performance. (ie backups)</li>
<li>Debugging sucks, testing rocks!</li>
<li>As your data grows, indexing may change (cardinality and selectivity change). Structuring may want to change. Make your schema as modular as your code. Make your code able to scale. Plan and embrace change, and get developers to do the same.</li>
</ol>
<p>Network Performance Tips:</p>
<ol>
<li>Minimize traffic by fetching only what you need.
<ol>
<li>Paging/chunked data retrieval to limit</li>
<li>Don&#8217;t use SELECT *</li>
<li>Be wary of lots of small quick queries if a longer query can be more efficient</li>
</ol>
</li>
<li>Use multi_query if appropriate to reduce round-trips</li>
<li>Use stored procedures to avoid bandwidth wastage</li>
</ol>
<p>OS Performance Tips:</p>
<ol>
<li>Use proper data partitions
<ol>
<li>For Cluster. Start thinking about Cluster *before* you need them</li>
</ol>
</li>
<li>Keep the database host as clean as possible. Do you really need a windowing system on that server?</li>
<li>Utilize the strengths of the OS</li>
<li>pare down cron scripts</li>
<li>create a test environment</li>
<li>source control schema and config files</li>
<li>for LVM innodb backups, restore to a different instance of MySQL so Innodb can roll forward</li>
<li>partition appropriately</li>
<li>partition your database when you have real data &#8212; do not assume you know your dataset until you have real data</li>
<li>Reduce swappiness of your OS</li>
</ol>
<p>MySQL Server Overall Tips:</p>
<ol>
<li>innodb_flush_commit=0 can help slave lag</li>
<li>Optimize for data types, use consistent data types. Use PROCEDURE ANALYSE() to help determine the smallest data type for your needs.</li>
<li>use optimistic locking, not pessimistic locking. try to use shared lock, not exclusive lock. share mode vs. FOR UPDATE</li>
<li>if you can, compress text/blobs</li>
<li>compress static data</li>
<li>don&#8217;t back up static data as often</li>
<li>enable and increase the query and buffer caches if appropriate</li>
<li>config params &#8211; <a title="http://docs.cellblue.nl/2007/03/17/easy-mysql-performance-tweaks/" href="http://docs.cellblue.nl/2007/03/17/easy-mysql-performance-tweaks/" rel="nofollow">http://docs.cellblue.nl/2007/03/17/easy-mysql-performance-tweaks/</a> is a good reference</li>
<li>Config variables &amp; tips:
<ol>
<li>use one of the supplied config files</li>
<li>key_buffer, unix cache (leave some RAM free), per-connection variables, innodb memory variables</li>
<li>be aware of global vs. per-connection variables</li>
<li>check SHOW STATUS and SHOW VARIABLES (GLOBAL|SESSION in 5.0 and up)</li>
<li>be aware of swapping esp. with Linux, &#8220;swappiness&#8221; (bypass OS filecache for innodb data files, innodb_flush_method=O_DIRECT if possible (this is also OS specific))</li>
<li>defragment tables, rebuild indexes, do table maintenance</li>
<li>If you use innodb_flush_txn_commit=1, use a battery-backed hardware cache write controller</li>
<li>more RAM is good so faster disk speed</li>
<li>use 64-bit architectures</li>
</ol>
</li>
<li>&#8211;skip-name-resolve</li>
<li>increase myisam_sort_buffer_size to optimize large inserts (this is a per-connection variable)</li>
<li>look up memory tuning parameter for on-insert caching</li>
<li>increase temp table size in a data warehousing environment (default is 32Mb) so it doesn&#8217;t write to disk (also constrained by max_heap_table_size, default 16Mb)</li>
<li>Run in SQL_MODE=STRICT to help identify warnings</li>
<li>/tmp dir on battery-backed write cache</li>
<li>consider battery-backed RAM for innodb logfiles</li>
<li>use &#8211;safe-updates for client</li>
<li>Redundant data is redundant</li>
<li>Keep an eye on <a title="http://cherry.world.edoors.com/COBFKUqnUdBY" href="http://cherry.world.edoors.com/COBFKUqnUdBY" rel="nofollow">buffer pool and keybuffer hit rate</a></li>
</ol>
<p>Storage Engine Performance Tips:</p>
<ol>
<li>InnoDB ALWAYS keeps the primary key as part of each index, so do not make the primary key very large</li>
<li>Utilize different storage engines on master/slave ie, if you need fulltext indexing on a table.</li>
<li>BLACKHOLE engine and replication is much faster than FEDERATED tables for things like logs.</li>
<li>Know your storage engines and what performs best for your needs, know that different ones exist.
<ol>
<li>ie, use MERGE tables ARCHIVE tables for logs</li>
<li>Archive old data &#8212; don&#8217;t be a pack-rat! 2 common engines for this are ARCHIVE tables and MERGE tables</li>
</ol>
</li>
<li>use row-level instead of table-level locking for OLTP workloads</li>
<li>try out a few schemas and storage engines in your test environment before picking one.</li>
</ol>
<p>Database Design Performance Tips:</p>
<ol>
<li>Design sane query schemas. don&#8217;t be afraid of table joins, often they are faster than denormalization</li>
<li>Don&#8217;t use boolean flags</li>
<li>Use Indexes</li>
<li>Don&#8217;t Index Everything</li>
<li>Do not duplicate indexes</li>
<li>Do not use large columns in indexes if the ratio of SELECTs:INSERTs is low.</li>
<li>Split out <a title="http://yoshinorimatsunobu.blogspot.com/2010/11/handling-long-textsblobs-in-innodb-1-to.html" href="http://yoshinorimatsunobu.blogspot.com/2010/11/handling-long-textsblobs-in-innodb-1-to.html" rel="nofollow">large blob elements</a> in InnoDB</li>
<li>be careful of redundant columns in an index or across indexes</li>
<li>Use a clever key and ORDER BY instead of MAX</li>
<li>Normalize first, and denormalize where appropriate.</li>
<li>Databases are not spreadsheets, even though Access really really looks like one. Then again, Access isn&#8217;t a real database</li>
<li>use INET_ATON and INET_NTOA for IP addresses, not char or varchar</li>
<li>make it a habit to REVERSE() email addresses, so you can easily search domains (this will help avoid wildcards at the start of LIKE queries if you want to find everyone whose e-mail is in a certain domain)</li>
<li>A NULL data type can take more room to store than NOT NULL</li>
<li>Avoid NULL in index attributes. Use 0 instead</li>
<li>Storing flags in a database can slow down execution due to a bad cardinality. Try using bit flags</li>
<li>Don&#8217;t store flags in a NULL and NOT NULL manner. Update from NULL -&gt; 1 is slower than 0 -&gt; 1</li>
<li>Choose appropriate character sets &amp; collations &#8212; UTF16 will store each character in 2 bytes, whether it needs it or not, latin1 is faster than UTF8.</li>
<li>Use Triggers wisely</li>
<li>Use <a title="http://marksverbiage.blogspot.com/2007/10/mysql-delaykeywrite-is-good.html" href="http://marksverbiage.blogspot.com/2007/10/mysql-delaykeywrite-is-good.html" rel="nofollow">delayed key wrote</a></li>
<li>use min_rows and max_rows to specify approximate data size so space can be pre-allocated and reference points can be calculated.</li>
<li>Use HASH indexing for indexing across columns with similar data prefixes</li>
<li>Use myisam_pack_keys for int data</li>
<li>be able to change your schema without ruining functionality of your code</li>
<li>segregate tables/databases that benefit from different configuration variables</li>
<li>Don&#8217;t access the last key part in a where clause with =</li>
<li>Abuse the system for optimiization you&#8217;re using with system dependant features like RTREE&#8217;s for <a title="http://jcole.us/blog/archives/2007/11/24/on-efficiently-geo-referencing-ips-with-maxmind-geoip-and-mysql-gis/" href="http://jcole.us/blog/archives/2007/11/24/on-efficiently-geo-referencing-ips-with-maxmind-geoip-and-mysql-gis/" rel="nofollow">optimized range queries</a></li>
</ol>
<p>Other:</p>
<ol>
<li>Hire a MySQL &#8482; Certified DBA</li>
<li>Know that there are many consulting companies out there that can help, as well as MySQL&#8217;s Professional Services.</li>
<li>Read and post to MySQL Planet at <a title="http://www.planetmysql.org" href="http://www.planetmysql.org/" rel="nofollow">http://www.planetmysql.org</a></li>
<li>Attend the yearly MySQL Conference and Expo or other conferences with MySQL tracks (link to the conference here)</li>
<li>Support your local User Group (link to forge page w/user groups here)</li>
</ol>
<p><a name="Authored_by"></a></p>
<h3>[<a title="Edit section: Authored by" href="safari-reader://forge.mysql.com/w/index.php?title=Top10SQLPerformanceTips&amp;action=edit&amp;section=2">edit</a>] Authored by</h3>
<p>Jay Pipes, Sheeri Kritzer, Bill Karwin, <a title="http://ronaldbradford.com" href="http://ronaldbradford.com/" rel="nofollow">Ronald Bradford</a>, Farhan &#8220;Frank Mash&#8221; Mashraqi, Taso Du Val, Ron Hu, Klinton Lee, Rick James, Alan Kasindorf, Eric Bergen, <a title="http://www.xarg.org" href="http://www.xarg.org/" rel="nofollow">Robert Eisele</a>, Kaj Arno, Joel Seligstein, Amy Lee, Sameer Joshi, Surat Singh Bhati</p>
</div>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://ricotek.net/uncategorized/top10sqlperformancetips/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Execute commands simultaneously on multiple servers Using PSSH/Cluster SSH/Multixterm</title>
		<link>http://ricotek.net/uncategorized/execute-commands-simultaneously-on-multiple-servers-using-psshcluster-sshmultixterm?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=execute-commands-simultaneously-on-multiple-servers-using-psshcluster-sshmultixterm</link>
		<comments>http://ricotek.net/uncategorized/execute-commands-simultaneously-on-multiple-servers-using-psshcluster-sshmultixterm#comments</comments>
		<pubDate>Sat, 18 Feb 2012 05:05:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://ricotek.net/?p=913</guid>
		<description><![CDATA[If you have multiple servers with similar or identical configurations (such as nodes in a cluster), it’s often difficult to make sure the contents and configuration of those servers are identical. It’s even more difficult when you need to make configuration modifications from the command line, knowing you’ll have to execute the … <a href="http://ricotek.net/uncategorized/execute-commands-simultaneously-on-multiple-servers-using-psshcluster-sshmultixterm"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>If you have multiple <a id="itxthook0" href="http://www.ubuntugeek.com/execute-commands-simultaneously-on-multiple-servers-using-psshcluster-sshmultixterm.html#" rel="nofollow">servers</a> with similar or identical configurations (such as nodes in a cluster), it’s often difficult to make sure the contents and configuration of those servers are identical. It’s even more difficult when you need to make configuration modifications from the command line, knowing you’ll have to execute the exact same command on a large number of systems .</p>
<p>&nbsp;</p>
<p>In this tutorial we will see some tools to execute one command on multiple remote servers using ssh.First you need to make sure you have ssh installed in your machine or you can install using the following command</p>
<blockquote><p>sudo aptitude install ssh</p></blockquote>
<p>Now we are going to see the following tools which does the required job we are looking for</p>
<p>1) Pssh</p>
<p>2) cluster ssh</p>
<p>3) Multixterm</p>
<p><strong>1) Pssh</strong></p>
<p>pssh provides a number of commands for executing against a group of <a id="itxthook1" href="http://www.ubuntugeek.com/execute-commands-simultaneously-on-multiple-servers-using-psshcluster-sshmultixterm.html#" rel="nofollow">computers</a>, using SSH. It’s most useful for operating on clusters of homogenously-configured hosts.</p>
<p>The package contains:</p>
<p>- Parallel ssh (parallel-ssh, upstream calls it pssh), executes commands on multiple hosts in parallel</p>
<p>- Parallel scp (parallel-scp, upstream calls it pscp), copies files to multiple remote hosts in parallel</p>
<p>- Parallel rsync (parallel-rsync, upstream calls it prsync), efficiently copies files to multiple hosts in parallel</p>
<p>- Parallel nuke (parallel-nuke, upstream calls it pnuke), kills processes on multiple remote hosts in parallel</p>
<p>- Parallel slurp (parallel-slurp, upstream calls it pslurp), copies files from multiple remote hosts to a central host in parallel</p>
<p>These tools are good for controlling large collections of nodes, where faster alternatives</p>
<p><strong>Install pssh in Ubuntu</strong></p>
<blockquote><p>sudo aptitude install pssh</p></blockquote>
<p><strong>pssh Syntax</strong></p>
<blockquote><p>pssh command -h hosts-file options</p></blockquote>
<p>-h &#8211;hosts   hosts file (each line “host[:port] [user]“)<br />
-l &#8211;user    username (OPTIONAL)<br />
-p &#8211;par     max number of parallel threads (OPTIONAL)<br />
-o &#8211;outdir  output directory for stdout files (OPTIONAL)<br />
-t &#8211;timeout timeout in seconds to do ssh to a host (OPTIONAL)<br />
-v &#8211;verbose turn on warning and diagnostic messages (OPTIONAL)<br />
-O &#8211;options SSH options (OPTIONAL)</p>
<p>where the hosts-file contains a list of all the hosts that you want to have the command executed on.</p>
<p><strong>pssh Examples</strong></p>
<p>The following example runs hostname on three machines (IPs or hostnames) specified in the file ips.txt using login irb2 and saves the output in /tmp/foo.</p>
<p>sudo cat ips.txt<br />
128.112.152.122<br />
18.31.0.190<br />
128.232.103.201</p>
<p>sudo pssh -h ips.txt -l irb2 -o /tmp/foo hostname</p>
<p>Success on 128.112.152.122:22<br />
Success on 18.31.0.190:22<br />
Success on 128.232.103.201:22</p>
<p>sudo ls /tmp/foo</p>
<p>128.112.152.122  128.232.103.201  18.31.0.190</p>
<p>sudo cat /tmp/foo/*</p>
<p>planetlab-1.cs.princeton.edu<br />
planetlab1.xeno.cl.cam.ac.uk<br />
planetlab1.lcs.mit.edu</p>
<p>By default, pssh uses at most 32 ssh processes in parallel to ssh to the various nodes. (This is somewhat important if you’re controlling hundreds or thousands of machines.) By default, it also uses a timeout of one minute to ssh to a node and obtain a result. For ssh commands that take longer than this (e.g., sleep 61), the -t option can be used. Note that pssh and pnuke have a default timeout of one minute. pscp and prsync have no default timeout, but one can be specified using the -t option.</p>
<p><strong>pscp</strong></p>
<p>Here’s an example of using pscp to copy files in parallel to a set of machines.</p>
<p>sudo  pscp -h ips.txt -l irb2 /etc/hosts /tmp/hosts</p>
<p>Success on 128.112.152.122:22<br />
Success on 18.31.0.190:22<br />
Success on 128.232.103.201:22</p>
<p>Using the -r option will perform a recursive copy for copying entire directories.</p>
<p><strong>2) cluster ssh</strong></p>
<p>administer multiple ssh or rsh shells simultaneouslyClusterSSH allows you to control multiple ssh or rsh sessions from a single input window. You can also configure clusters of machines for easy invocation and interact with individual terminal windows during a session.</p>
<p><strong>Install Cluster ssh in Ubuntu</strong></p>
<blockquote><p>sudo aptitude install clusterssh</p></blockquote>
<p><strong>Configuration Files</strong></p>
<p>This /etc/clusters file is cluster tag <a id="itxthook2" href="http://www.ubuntugeek.com/execute-commands-simultaneously-on-multiple-servers-using-psshcluster-sshmultixterm.html#" rel="nofollow">database</a>. Contains a list of tags and hostnames, in the form</p>
<blockquote><p>&lt;tag&gt; [&lt;username&gt;@]hostname [...]</p></blockquote>
<p>Newlines and comments (delimited with a #) are ignored.</p>
<p>Cluster definitions can also be added to the $HOME/.csshrc file</p>
<p>This /etc/csshrc file is Global configuration file, sourced by all users. Can be generated by:</p>
<blockquote><p>sudo cssh -u &gt; /etc/csshrc</p></blockquote>
<p>$HOME/.csshrc</p>
<p>Per user configuration file. Can be generated by:</p>
<p>cssh -u &gt; /etc/csshrc &lt;/tt&gt;</p>
<p>To add a cluster definition to this file, use the following format</p>
<p>cluster_tag1 = server1 server2 user@server3<br />
cluster_tag2 = server4 server5<br />
clusters = cluster_tag1 cluster_tag2</p>
<p>Be aware of using “reserved names” and no check is currently performed for them.</p>
<p><strong>Using Cluster SSH</strong></p>
<p>If you want to perform the same command on the three servers one, two, &amp; three use the following command</p>
<blockquote><p>sudo cssh one two three</p></blockquote>
<p>This will open three consoles, one for each <a id="itxthook3" href="http://www.ubuntugeek.com/execute-commands-simultaneously-on-multiple-servers-using-psshcluster-sshmultixterm.html#" rel="nofollow">server</a>, over an ssh connection, and one little console to type your command.</p>
<p><strong>3) Multixterm</strong></p>
<p>Expect is a program that talks to other interactive programs according to a script. Expect is useful for running any program which requires interaction between the program and the user.In Ubuntu multixterm included in expect package.</p>
<p><strong>Install expect in Ubuntu</strong></p>
<blockquote><p>sudo aptitude install expect</p></blockquote>
<p><strong>Multixterm Syntax</strong></p>
<blockquote><p>multixterm -[ args ] “command arg1 arg2″ server1 server2…</p></blockquote>
<p><strong>Arguments</strong></p>
<p>-xa &#8211; The optional -xa argument indicates arguments to pass to xterm.</p>
<p>-xc &#8211; The optional -xc argument indicates a command to be run in each named xterm (see -xn). With no -xc argument, the command is the current shell.</p>
<p>-xd &#8211; The optional -xd argument indicates a directory to search for files that will appear in the Files menu. By default, the directory is: ~/lib/multixterm</p>
<p>-xf &#8211; The optional -xf argument indicates a file to be read at startup. See FILES below for more info.</p>
<p>-xn &#8211; The optional -xn argument indicates a name for each xterm. This name will also be substituted for any %n in the command argument (see -xc).</p>
<p>-xv &#8211; The optional -xv flag puts multixterm into a verbose mode where it will describe some of the things it is doing internally. The verbose output is not intended to be understandable to anyone but the author.</p>
<p><strong>Multixterm Examples</strong></p>
<p>The following command line starts up two xterms using ssh to the hosts 192.168.2.100 and 192.168.2.101</p>
<blockquote><p>sudo multixterm -xc “ssh root@%n” 192.168.2.100 192.168.2.101</p></blockquote>
<p>-xc &#8211; The optional -xc argument indicates a command to be run in each named xterm (see -xn). With no -xc argument, the command is the current shell.</p>
<p>ssh root@%n : ssh is a command to connect remote server with root user. This name will also be substituted for any %n in the command argument.</p>
]]></content:encoded>
			<wfw:commentRss>http://ricotek.net/uncategorized/execute-commands-simultaneously-on-multiple-servers-using-psshcluster-sshmultixterm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Managing Multiple Linux Servers with ClusterSSH</title>
		<link>http://ricotek.net/uncategorized/managing-multiple-linux-servers-with-clusterssh?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=managing-multiple-linux-servers-with-clusterssh</link>
		<comments>http://ricotek.net/uncategorized/managing-multiple-linux-servers-with-clusterssh#comments</comments>
		<pubDate>Sat, 18 Feb 2012 05:02:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://ricotek.net/?p=909</guid>
		<description><![CDATA[If you&#8217;re a Linux system administrator, chances are you&#8217;ve got more than one machine that you&#8217;re responsible for on a daily basis. You may even have a bank of machines that you maintain that are similar — a farm of Web servers, for example. If you have a need to … <a href="http://ricotek.net/uncategorized/managing-multiple-linux-servers-with-clusterssh"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re a Linux system administrator, chances are you&#8217;ve got more than one machine that you&#8217;re responsible for on a daily basis. You may even have a bank of machines that you maintain that are similar — a farm of Web servers, for example. If you have a need to type the same command into several machines at once, you can login to each one with SSH and do it serially, or you can save yourself a lot of time and effort and use a tool like ClusterSSH.</p>
<p>ClusterSSH is a Tk/Perl wrapper around standard Linux tools like XTerm and SSH. As such, it&#8217;ll run on just about any POSIX-compliant OS where the libraries exist — I&#8217;ve run it on Linux, Solaris, and Mac OS X. It requires the Perl libraries Tk (<code>perl-tk</code> on Debian or Ubuntu) and X11::Protocol (<code>libx11-protocol-perl</code> on Debian or Ubuntu), in addition to xterm and OpenSSH.</p>
<h3>Installation</h3>
<p>Installing ClusterSSH on a Debian or Ubuntu system is trivial — a simple <code>sudo apt-get install clusterssh</code> will install it and its dependencies. It is also packaged for use with Fedora, and it is installable via the ports system on FreeBSD. There&#8217;s also a MacPorts version for use with Mac OS X, if you use an Apple machine. Of course, it can also be compiled from source.</p>
<h3>Configuration</h3>
<p>ClusterSSH can be configured either via its global configuration file — <code>/etc/clusters</code>, or via a file in the user&#8217;s home directory called <code>.csshrc</code>. I tend to favor the user-level configuration as that lets multiple people on the same system to setup their ClusterSSH client as they choose. Configuration is straightforward in either case, as the file format is the same. ClusterSSH defines a &#8220;cluster&#8221; as a group of machines that you&#8217;d like to control via one interface. With that in mind, you enumerate your clusters at the top of the file in a &#8220;clusters&#8221; block, and then you describe each cluster in a separate section below.</p>
<p>For example, let&#8217;s say I&#8217;ve got two clusters, each consisting of two machines. &#8220;Cluster1&#8243; has the machines &#8220;Test1&#8243; and &#8220;Test2&#8243; in it, and &#8220;Cluster2&#8243; has the machines &#8220;Test3&#8243; and &#8220;Test4&#8243; in it. The <code>~.csshrc</code> (or<code>/etc/clusters</code>) control file would look like this:</p>
<p><code>clusters = cluster1 cluster2</code></p>
<p>cluster1 = test1 test2<br />
cluster2 = test3 test4</p>
<p>You can also make meta-clusters — clusters that refer to clusters. If you wanted to make a cluster called &#8220;all&#8221; that encompassed all the machines, you could define it two ways. First, you could simply create a cluster that held all the machines, like the following:</p>
<p><code>clusters = cluster1 cluster2 all</code></p>
<p>cluster1 = test1 test2<br />
cluster2 = test3 test4<br />
all = test1 test2 test3 test4</p>
<p>However, my preferred method is to use a meta-cluster that encompasses the other clusters:</p>
<p><code>clusters = cluster1 cluster2 all</code></p>
<p>cluster1 = test1 test2<br />
cluster2 = test3 test4<br />
all = cluster1 cluster2</p>
<p>&nbsp;</p>
<div><a href="http://www.linux.com/images/stories/cssh1.png" target="_blank"><img title="Figure 1: Lauching ClusterSSH" src="http://www.linux.com/images/stories/cssh1.png" alt="ClusterSSH" width="251" height="188" align="left" border="0" hspace="6" vspace="6" /></a>Figure 1: Lauching ClusterSSH</div>
<p>&nbsp;</p>
<p>By calling out the &#8220;all&#8221; cluster as containing cluster1 and cluster2, if either of those clusters ever change, the change is automatically captured so you don&#8217;t have to update the &#8220;all&#8221; definition. This will save you time and headache if your .csshrc file ever grows in size.</p>
<h3>Using ClusterSSH</h3>
<p>Using ClusterSSH is similar to launching SSH by itself. Simply running <code>cssh -l &lt;username&gt; &lt;clustername&gt;</code>will launch ClusterSSH and log you in as the desired user on that cluster. In the figure below, you can see I&#8217;ve logged into &#8220;cluster1&#8243; as myself. The small window labeled &#8220;CSSH [2]&#8221; is the Cluster SSH console window. Anything I type into that small window gets echoed to all the machines in the cluster — in this case, machines &#8220;test1&#8243; and &#8220;test2&#8243;. In a pinch, you can also login to machines that aren&#8217;t in your .csshrc file, simply by running <code>cssh -l &lt;username&gt; &lt;machinename1&gt; &lt;machinename2&gt; &lt;machinename3&gt;</code>.</p>
<p>If I want to send something to one of the terminals, I can simply switch focus by clicking in the desired XTerm, and just type in that window like I usually would. ClusterSSH has a few menu items that really help when dealing with a mix of machines. As per the figure below, in the &#8220;Hosts&#8221; menu of the ClusterSSH console there&#8217;s are several options that come in handy.</p>
<p>&#8220;Retile Windows&#8221; does just that if you&#8217;ve manually resized or moved something. &#8220;Add host(s) or Cluster(s)&#8221; is great if you want to add another set of machines or another cluster to the running ClusterSSH session. Finally, you&#8217;ll see each host listed at the bottom of the &#8220;Hosts&#8221; menu. By checking or unchecking the boxes next to each hostname, you can select which hosts the ClusterSSH console will echo commands to. This is handy if you want to exclude a host or two for a one-off or particular reason. The final menu option that&#8217;s nice to have is under the &#8220;Send&#8221; menu, called &#8220;Hostname&#8221;. This simply echoes each machine&#8217;s hostname to the command line, which can be handy if you&#8217;re constructing something host-specific across your cluster.</p>
<p>&nbsp;</p>
<div><a href="http://www.linux.com/images/stories/cssh2.png" target="_blank"><img title="Figure 2: Resize Windows" src="http://www.linux.com/images/stories/cssh2.png" alt="Resize Windows" width="251" height="188" align="right" border="0" hspace="6" vspace="6" /></a>Figure 2: Resize Windows</div>
<p>&nbsp;</p>
<h3>Caveats with ClusterSSH</h3>
<p>Like many UNIX tools, ClusterSSH has the potential to go horribly awry if you aren&#8217;t <strong><em>very</em></strong> careful with its use. I&#8217;ve seen ClusterSSH mistakes take out an entire tier of Web servers simply by propagating a typo in an Apache configuration. Having access to multiple machines at once, possibly as a privileged user, means mistakes come at a great cost. Take care, and double-check what you&#8217;re doing before you punch that Enter key.</p>
<h3>Conclusion</h3>
<p>ClusterSSH isn&#8217;t a replacement for having a configuration management system or any of the other best practices when managing a number of machines. However, if you need to do something in a pinch outside of your usual toolset or process, or if you&#8217;re doing prototype work, ClusterSSH is indispensable. It can save a lot of time when doing tasks that need to be done on more than one machine, but like any power tool, it can cause a lot of damage if used haphazardly.</p>
]]></content:encoded>
			<wfw:commentRss>http://ricotek.net/uncategorized/managing-multiple-linux-servers-with-clusterssh/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
