<?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>Pramatr Blog &#187; Connection Pool</title>
	<atom:link href="http://www.pramatr.com/blog/tag/connection-pool/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pramatr.com/blog</link>
	<description>A collection of articles from pramatr.com on technology, security, software and anything we find interesting</description>
	<lastBuildDate>Mon, 29 Mar 2010 19:48:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Embedded Database Performance: Handle With Care</title>
		<link>http://www.pramatr.com/blog/2009/02/10/embedded-database-performance-handle-with-car/</link>
		<comments>http://www.pramatr.com/blog/2009/02/10/embedded-database-performance-handle-with-car/#comments</comments>
		<pubDate>Tue, 10 Feb 2009 06:00:38 +0000</pubDate>
		<dc:creator>pramatr</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Refactoring]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Connection Pool]]></category>
		<category><![CDATA[Improvement]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Jdbc]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Smells]]></category>

		<guid isPermaLink="false">http://pramatr.com/?p=11</guid>
		<description><![CDATA[Embedded databases are proving pretty popular with many teams finding their usage extremely appealing. Many embedded databases have impressive features; easy to integrate into the software, low administration requirements, very low footprint and generally extremely fast. It is for this last reason that some people look to these databases, but it is also for this reason [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Embedded_database">Embedded databases</a> are proving pretty popular with many teams finding their usage extremely appealing. Many embedded databases have impressive features; easy to integrate into the software, low administration requirements, very low footprint and generally extremely fast. It is for this last reason that some people look to these databases, but it is also for this reason that they need to be handled with care.</p>
<p>Just <a href="http://hsqldb.org/web/openoffice.html">like</a> OpenOffice, a previous project I worked on used an embedded version of <a href="http://hsqldb.org/">HSQLDB</a>. We had started to have several performance problems so engaged in some profiling to find potential areas for improvement. After staring at several screens full of SQL debug, one thing became apparent; our system was producing a huge number of SQL statements. This was accompanied by the realisation that it was also producing a huge number of exactly the same SQL statements.</p>
<p>As the embedded database was extremely fast, there had never been any performance problems before. In fact the database was not the bottleneck in many of the application operations. As the application grew more complex however, performance problems began to arise quite quickly. These problems only got worse when the numbers started to increase. Complexity + Scaling != Success. The extemely fast embedded database was now starting to be a real problem, some serious changes needed to be made.</p>
<p>Many of the database performance problems were resolved quite quickly by simply re-learning the most basic best practices, just because the embedded database was quick these should not have been ignored;</p>
<ul>
<li>Connection pooling can improve performance</li>
<li>Statement caching can improve performance</li>
<li>Batching statements can improve performance</li>
<li>Performing <a href="http://pramatr.com/2009/02/05/sql-n-1-selects-explained/">SQL n + 1 selects</a> are a bad idea regardless of how quick the database is</li>
<li>Caching common SQL results can improve performance</li>
<li>The database needs to be profiled to see exactly what SQL is getting executed against it</li>
</ul>
<p>It may be possible to ignore these issues early in the project, but as the complexity increases and the application is expected to scale they can begin to be exposed. Embedded databases performance can be impressive, but make sure you handle with care.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pramatr.com/blog/2009/02/10/embedded-database-performance-handle-with-car/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spring JdbcTemplate: The Phantom Performance Problem</title>
		<link>http://www.pramatr.com/blog/2008/08/19/spring-jdbctemplate-the-phantom-performance-problem/</link>
		<comments>http://www.pramatr.com/blog/2008/08/19/spring-jdbctemplate-the-phantom-performance-problem/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 15:52:00 +0000</pubDate>
		<dc:creator>pramatr</dc:creator>
				<category><![CDATA[Spring]]></category>
		<category><![CDATA[Connection Pool]]></category>
		<category><![CDATA[Jdbc]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Transactions]]></category>

		<guid isPermaLink="false">http://pramatr.com/2007/08/19/spring-jdbctemplate-the-phantom-performance-problem/</guid>
		<description><![CDATA[Over the past few years there have been numerous posts on Spring Forum regarding the performance of JdbcTemplate. The majority of these are complaining about poor performance of JdbcTemplate in comparison to pure Jdbc. I thought this topic had been done to death already, but a friend of mine told me his developers were having [...]]]></description>
			<content:encoded><![CDATA[<p>Over the past few years there have been numerous posts on <a href="http://forum.springframework.org/">Spring Forum</a> regarding the performance of <a href="http://www.springframework.org/docs/api/org/springframework/jdbc/core/JdbcTemplate.html">JdbcTemplate</a>. The majority of these are complaining about poor performance of JdbcTemplate in comparison to pure Jdbc. I thought this topic had been done to death already, but a friend of mine told me his developers were having performance problems with JdbcTemplate as recently as last week. They had switched back to Jdbc after some performance comparisons had proven JdbcTemplate was significantly slower.</p>
<p>So what makes JdbcTemplate so much slower than pure Jdbc? In a word&#8230;&#8230;.. nothing. JdbcTemplate does a great job of removing the try/catch/finally/try/catch code we used to write with Jdbc, but under the covers it&#8217;s just doing the same old stuff we used to do. It&#8217;s getting hold of a <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/sql/Connection.html">connection</a>, executing a <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/sql/PreparedStatement.html">statement</a>, possibly mapping a <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/sql/ResultSet.html">result set</a> to an object, converting any exceptions for us and releasing the connection. That&#8217;s pretty much it, it&#8217;s a thin wrapper around Jdbc that makes it usable in the real world.</p>
<p>So why do people report performance problems with JdbcTemplate? I took the opportunity to review the comparison that had reported such terrible performance compared to Jdbc. After a couple of minutes reviewing the comparison it was quite obvious it was fatally flawed, not only was it configured differently, it wasn&#8217;t testing the same thing. Looking at the comparisons that have been posted in the past on Spring Forum, they typically suffer from the same problems. The most common is they generally don&#8217;t perform a <a href="http://www.ise5-14.org.uk/Prim3/New_Guidelines/Investigations/Fair_test.htm">fair test</a>. Lets look at the typical problems the comparisons face before seeing the comparison results once the problems were fixed.<br />
<span id="more-81"></span></p>
<ol>
<li>Connection Pool vs Single Connection</li>
<p>One test uses a <a href="http://sourceforge.net/projects/c3p0">connection pool</a> and the other will acquire a new <a href="http://www.springframework.org/docs/api/org/springframework/jdbc/datasource/DriverManagerDataSource.html">connection</a> every time a statement is executed. This can have differing effects on the test results depending on the initial pool size. If this is set to a high value then typically the connection pool tests will perform slower. Either way, use the same data source for both tests with the same settings.</p>
<li>Transactions</li>
<p>One test uses transactions and the other executes non-transactionally, or the transactions are applied at different levels. There&#8217;s no point wrapping each query execution in a transaction in one test and in the other test applying it to the <a href="http://www.martinfowler.com/eaaCatalog/serviceLayer.html">service layer</a>. This was actually one of the problems with the original performance comparison. The transactions were applied at the service layer in one test and the <a href="http://java.sun.com/blueprints/patterns/DAO.html">DAO</a> in the other.</p>
<li>Jdbc <a href="http://www.springframework.org/docs/api/org/springframework/jdbc/core/RowMapper.html">RowMapper</a> equivalent doesn&#8217;t do anything</li>
<p>This is the most common problem I&#8217;ve seen. Although the pure Jdbc version of the code executes a query, the result set is ignored as the results are not processed and mapped into the object representations. This obviously shows a massive improvement over JdbcTemplate as it&#8217;s not actually doing anything. If it isn&#8217;t processing the results, it&#8217;s going to be quicker!</p>
<li><a href="http://java.sun.com/j2se/1.5.0/docs/api/java/sql/PreparedStatement.html">Prepared Statements</a> vs String-based queries</li>
<p>Prepared statements are potentially going to be more efficient than string-based queries (depending on platform). Initially the prepared statement is going to be more expensive to create, but if it&#8217;s reused it should produce improved performance as it should be available from the statement cache.</p>
<li><a href="http://www.onjava.com/pub/a/onjava/excerpt/javaentnut_2/index3.html?page=">Batch Statements</a></li>
<p>One test uses batched prepared statements and the other executes a separate prepared statement.</p>
<li>Creating a new <a href="http://www.springframework.org/docs/api/org/springframework/context/ApplicationContext.html">ApplicationContext</a> for every test run</li>
<p>Although this is the least common problem, it was actually one of the problems in the aforementioned comparison. If one test uses Spring and the other doesn&#8217;t, either create the ApplicationContext outside of the test or at least ensure it&#8217;s construction isn&#8217;t included in the time taken to complete the test.
</ol>
<p>Let&#8217;s have a look at the performance comparison that was discussed at the beginning of the blog and also the <strong>real</strong> statistics it produced. The test consisted of creating, updating, deleting and retrieving a number of users. In this example the number of users was set to one thousand, and the test was run one hundred times to give an average time for each operation. For the sake of brevity I&#8217;ve only included the code here for retrieving and updating the users, the code for creating and deleting them however followed exactly the same pattern.</p>
<p>This is the pure Jdbc code that retrieves all the users and update the user&#8217;s password.</p>
<blockquote><pre><span style="font-size:small;"><strong>public</strong> <span style="color:#2040a0;">List</span><span style="color:#4444ff;">&lt;</span><span style="color:#2040a0;">User</span><span style="color:#4444ff;">&gt;</span> <span style="color:#2040a0;">getUsers</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
	<strong>return</strong> <span style="color:#2040a0;">jdbcTemplate</span>.<span style="color:#2040a0;">query</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"SELECT * FROM user_details"</span>, <strong>new</strong> <span style="color:#2040a0;">RowMapper</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
		<strong>public</strong> <span style="color:#2040a0;">Object</span> <span style="color:#2040a0;">mapRow</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">ResultSet</span> <span style="color:#2040a0;">rs</span>, <strong>int</strong> <span style="color:#2040a0;">rowNum</span><span style="color:#4444ff;"><strong>)</strong></span> <strong>throws</strong> <span style="color:#2040a0;">SQLException</span> <span style="color:#4444ff;"><strong>{</strong></span>
			<span style="color:#2040a0;">String</span> <span style="color:#2040a0;">username</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">rs</span>.<span style="color:#2040a0;">getString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"username"</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
			<span style="color:#2040a0;">String</span> <span style="color:#2040a0;">password</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">rs</span>.<span style="color:#2040a0;">getString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"password"</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
			<strong>return</strong> <strong>new</strong> <span style="color:#2040a0;">User</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">username</span>, <span style="color:#2040a0;">password</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
		<span style="color:#4444ff;"><strong>}</strong></span>
	<span style="color:#4444ff;"><strong>}</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
<span style="color:#4444ff;"><strong>}</strong></span>

<strong>public</strong> <strong>void</strong> <span style="color:#2040a0;">updateUsers</span><span style="color:#4444ff;"><strong>(</strong></span><strong>final</strong> <span style="color:#2040a0;">List</span><span style="color:#4444ff;">&lt;</span><span style="color:#2040a0;">User</span><span style="color:#4444ff;">&gt;</span> <span style="color:#2040a0;">users</span><span style="color:#4444ff;"><strong>)</strong></span> <strong>throws</strong> <span style="color:#2040a0;">Exception</span> <span style="color:#4444ff;"><strong>{</strong></span>
	<strong>this</strong>.<span style="color:#2040a0;">jdbcTemplate</span>.<span style="color:#2040a0;">batchUpdate</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"UPDATE user_details SET password = ? WHERE username = ?"</span>,
				<strong>new</strong> <span style="color:#2040a0;">BatchPreparedStatementSetter</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
		<strong>public</strong> <strong>void</strong> <span style="color:#2040a0;">setValues</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">PreparedStatement</span> <span style="color:#2040a0;">ps</span>, <strong>int</strong> <span style="color:#2040a0;">i</span><span style="color:#4444ff;"><strong>)</strong></span> <strong>throws</strong> <span style="color:#2040a0;">SQLException</span> <span style="color:#4444ff;"><strong>{</strong></span>
			<span style="color:#2040a0;">User</span> <span style="color:#2040a0;">user</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">users</span>.<span style="color:#2040a0;">get</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">i</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
			<span style="color:#2040a0;">ps</span>.<span style="color:#2040a0;">setString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#ff0000;">1</span>, <span style="color:#2040a0;">PasswordObfuscator</span>.<span style="color:#2040a0;">obfuscate</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">user</span>.<span style="color:#2040a0;">getPassword</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
			<span style="color:#2040a0;">ps</span>.<span style="color:#2040a0;">setString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#ff0000;">2</span>, <span style="color:#2040a0;">user</span>.<span style="color:#2040a0;">getUsername</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
		<span style="color:#4444ff;"><strong>}</strong></span>

		<strong>public</strong> <strong>int</strong> <span style="color:#2040a0;">getBatchSize</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
			<strong>return</strong> <span style="color:#2040a0;">users</span>.<span style="color:#2040a0;">size</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
		<span style="color:#4444ff;"><strong>}</strong></span>
	<span style="color:#4444ff;"><strong>}</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
<span style="color:#4444ff;"><strong>}</strong></span></span></pre>
</blockquote>
<p>And finally let&#8217;s have a look at those all important numbers.</p>
<p>Jdbc DAO<br />
insert: <strong>360ms</strong>, fetch: <strong>7ms</strong>, update: <strong>276ms</strong>, delete: <strong>136ms</strong></p>
<p>JdbcTemplate DAO<br />
insert: <strong>363ms</strong>, fetch: <strong>5ms</strong>, update: <strong>278ms</strong>, delete: <strong>133ms</strong></p>
<p>Transactional Jdbc DAO<br />
insert: <strong>963ms</strong>, fetch: <strong>6ms</strong>, update: <strong>276ms</strong>, delete: <strong>131ms</strong></p>
<p>Transactional JdbcTemplate DAO<br />
insert: <strong>948ms</strong>, fetch: <strong>6ms</strong>, update: <strong>274ms</strong>, delete: <strong>131ms</strong></p>
<p>As expected there&#8217;s really not that much in it. Once the issues were fixed in the original comparison they come out pretty much the same. JdbcTemplate doesn&#8217;t have the performance problems the original comparison reported and actually shows pretty much the same performance as pure Jdbc. So the moral of the story&#8230;&#8230;. if you are doing a comparison make sure you are comparing the same things and most importantly whatever you tweak, make it a <a href="http://www.ise5-14.org.uk/Prim3/New_Guidelines/Investigations/Fair_test.htm">fair test</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pramatr.com/blog/2008/08/19/spring-jdbctemplate-the-phantom-performance-problem/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
