<?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>Nevermind &#187; mysql</title>
	<atom:link href="http://www.nevermind.co.nz/tag/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nevermind.co.nz</link>
	<description>Epiq Failjure</description>
	<lastBuildDate>Tue, 07 Jun 2011 09:50:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Speeding up INSERTs on MySQL</title>
		<link>http://www.nevermind.co.nz/2009/10/13/speeding-up-inserts-on-mysql/</link>
		<comments>http://www.nevermind.co.nz/2009/10/13/speeding-up-inserts-on-mysql/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 10:00:06 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[TechTidBits]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.nevermind.co.nz/?p=345</guid>
		<description><![CDATA[Was working on a problem today that required a lot of bulk inserts to a MySQL table. I was getting about 200 inserts/second on my development system, which is OK considering there was some minor processing going on. Since some batches can contain well over a million rows, I started working on how to optimise [...]]]></description>
			<content:encoded><![CDATA[<p>Was working on a problem today that required a lot of bulk inserts to a MySQL table. I was getting about 200 inserts/second on my development system, which is OK considering there was some minor processing going on.</p>
<p>Since some batches can contain well over a million rows, I started working on how to optimise these queries so we can get them in there faster.</p>
<p><strong>Firstly</strong>, watch your indexes on the table. Obviously the more indexes you have on the table the more work the DB has to do on INSERT to maintain them.</p>
<p><strong>Second</strong>, if possible, ditch your ORM. Instead of building and hydrating objects for each row in the table used direct/prepared queries. Most ORMs worth their salt can handle this. i.e. Propel can give you direct access to the underlying <a href="http://php.net/manual/en/book.pdo.php">PDO</a> connection to use your prepared statements.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/** @var $con PDO */</span>
<span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> Propel<span style="color: #339933;">::</span><span style="color: #004000;">getConnection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Obviously if you have business logic tied up in your objects, it&#8217;s best to use them instead of duplicating code.</p>
<p><strong>Third</strong>, lock the table for a batch of inserts. Here&#8217;s some sample code</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> Propel<span style="color: #339933;">::</span><span style="color: #004000;">getConnection</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">beginTransaction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$rowsToInsert</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">%</span> <span style="color: #cc66cc;">100</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">commit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">beginTransaction</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  TablePeer<span style="color: #339933;">::</span><span style="color: #004000;">insertUsingPreparedStatement</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$i</span><span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>If your using MyISAM you can lock the table using the LOCK TABLE statement</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">exec</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'LOCK TABLES table_name WRITE'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">exec</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'UNLOCK TABLES'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Depending on how important your data is you can change the (100) value in the $i % conditional to higher or lower. The reason this speeds up Inserts so much is that MySQL won&#8217;t flush it&#8217;s write cache to the disk until the transaction is finished, as opposed to every INSERT statement. However, having unflushed data in your cache is dangerous because it may disappear if something happens to the DB server, or get rolled back if your script carks it. Also, since a transaction/lock table call will stop all other access to the table, if it&#8217;s frequently read from those queries will be waiting on locks, so it&#8217;s good to refresh them frequently.</p>
<p>Using these three methods I almost tripled the performance of my script which now inserts between 550-600 rows per second. Win!</p>
<p>There&#8217;s some more tips over <a href="http://dev.mysql.com/doc/refman/5.1/en/insert-speed.html">here in the MySQL manual</a> and some of the comments are quite helpful too.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nevermind.co.nz/2009/10/13/speeding-up-inserts-on-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

