The Artima Developer Community
Sponsored Link

Java Buzz Forum
Comparing Statements, PreparedStatements and JSTL on a MySQL DB

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Russell Beattie

Posts: 727
Nickname: rbeattie
Registered: Aug, 2003

Russell Beattie is a Mobile Internet Developer
Comparing Statements, PreparedStatements and JSTL on a MySQL DB Posted: Mar 20, 2004 9:55 PM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Russell Beattie.
Original Post: Comparing Statements, PreparedStatements and JSTL on a MySQL DB
Feed Title: Russell Beattie Notebook
Feed URL: http://www.russellbeattie.com/notebook/rss.jsp?q=java,code,mobile
Feed Description: My online notebook with thoughts, comments, links and more.
Latest Java Buzz Posts
Latest Java Buzz Posts by Russell Beattie
Latest Posts From Russell Beattie Notebook

Advertisement
So I was using some JSTL SQL queries to produce XML pages. Doing it in JSTL is quick an easy and I figured wouldn't be that much slower than doing it in a servlet or JSP with scriptlet. Wow, was I wrong.

First, though, let me say that I was thinking about it in the bathroom (where I do most of my thinking) and I thought "I bet you deep inside of JSTL, they're only using Statements, not PreparedStatements" - so I went diving into the chaos that is the JSTL source code and sure enough, I found this deep in the heart of the QueryTagSupport.java class:

try {
    PreparedStatement ps = conn.prepareStatement(sqlStatement);
    setParameters(ps, parameters);
    ResultSet rs = ps.executeQuery();
    result = new ResultImpl(rs, startRow, maxRows);
        ps.close();
}
catch (Throwable e) {
    throw new JspException(sqlStatement + ": " + e.getMessage(), e);
}
Wow, I thought. That's horrible! JSTL is creating a prepared statement for every even if there are no parameters being sent. Oof. That must be a major hit, I thought, as I've seen articles that stated that PreparedStatements can be 65 times as slow as Statements.

I happened to be online with Erik at the time, so I told him what I found and he told me that it was up to the driver, actually. Then he went routing around in the MySQL JDBC driver and sure enough, there's no fundamental difference between the two methods when it talks to the server. To prove it, I decided to write a quick test. First, I just did a Statement verses a PreparedStatement, looking up one record (it's the lookup that counts, since the Results will be the same) and returning it 10,000 times. The results amazed me: Statements came back in around 1.7 seconds, and Prepared statements around 1.9. No big difference at all - even when I moved the prepareStatement() outside the loop. I increased the number of queries and there still was no major difference.

Then after chatting with Erik for another bit, we decided to test the JSTL code as well to see if it had any performance hits. Wow again. The first query of 100,000 hits took so long I thought I wacked my server, so I modified the code to not print out the results, backed the loops down to 10,000 and ran the page again.

Here's the test code:

<%@ page import="java.sql.*, javax.naming.*, javax.sql.*, java.io.*, java.util.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<html>
<body>
<sql:setDataSource dataSource="jdbc/TestDS"/>
<p>
<%	


	Context initCtx = new InitialContext();
	Context envCtx = (Context) initCtx.lookup("java:/comp/env");  
	DataSource ds = (DataSource)envCtx.lookup("jdbc/TestDS");  
	
	Connection conn = ds.getConnection(); 
	
	
	long time = System.currentTimeMillis();       	
	
	
	for(int i = 0; i < 10000; i++ )
	{	
		Statement s = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
		ResultSet rs = s.executeQuery("select * from test where id=100803");
		while(rs.next()){
			//out.write(rs.getString("id"));
		}
		rs.close();
		s.close();
	}
 		
     
	out.write("\n\n Statement:" + (System.currentTimeMillis() - time) + "\n\n");

	time = System.currentTimeMillis();

	for(int i = 0; i < 10000; i++ )
	{
	    PreparedStatement ps = conn.prepareStatement("select * from test where id = ?");
	    ps.setInt(1, 100803);
	    ResultSet rs = ps.executeQuery();
		while(rs.next()){
			//out.write(rs.getString("id"));
		}	        
	    rs.close();
	    ps.close();
	}

     out.write("\n\n PreparedStatement (in):" + (System.currentTimeMillis() - time) + "\n\n");

	time = System.currentTimeMillis();
	PreparedStatement ps = conn.prepareStatement("select * from test where id = ?");
	for(int i = 0; i < 10000; i++ )
	{
	    ps.setInt(1, 100803);
	    ResultSet rs = ps.executeQuery();
		while(rs.next()){
			//out.write(rs.getString("id"));
		}	        
	    rs.close();

	}
	ps.close();
     out.write("\n\n PreparedStatement (out):" + (System.currentTimeMillis() - time) + "\n\n");



	time = System.currentTimeMillis();

	for(int i = 0; i < 10000; i++ )
		{  	
%><sql:query var="rs">select * from test where id=100803</sql:query><c:forEach var="row" items="${rs.rows}"></c:forEach><%	} 

	out.write("\n\n JSTL:" + (System.currentTimeMillis() - time) + "\n\n");
	
%>

</p>
</body>
</html>

The results are astounding:

Statement: 1,792ms
PreparedStatement (in): 1,969ms
PreparedStatement (out): 1,626ms
JSTL: 28,596ms

Yes, using JSTL is around 10 times slower than a PreparedStatement, and it scales for shit. Holy Crap! What the hell is that code doing? Well, first, it's throwing the entire results into a HashMap, that's definitely not particularly efficient, but then after that I'm not sure. What I do know is that a regular scriptlet .jsp page that produces a .java file of around 60 lines of code, produces a .java file that's 500(!!) lines of code if I duplicate the functionality using JSTL.

That's all serious food for thought. I really like JSTL because it's quick to develop in, but not if there's this much of a performance hit. I need to test the XML stuff as well, since I'm using that in lots of different places. I just can't believe how innefficient that SQL stuff is! I'm definitely re-writing all the quick-and-dirty XML generating code I had done using the JSTL SQL tags though. No question.

-Russ

Read: Comparing Statements, PreparedStatements and JSTL on a MySQL DB

Topic: John Kerry and Ben and Mena Previous Topic   Next Topic Topic: Java & Scripting Overview

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use