Back to Basics: Statement vs. Prepared Statement

“What is the difference between Statement and Prepared Statement?” this is one of my favorite interview question. Most of the interviewee will say “Statement is not precompiled, prepared statements are precompiled, hence prepared statement will faster than statement”. My next question would be “What do you mean precompile”, the answer will be “the SQL gets compiled and reused”. My last question would be “In which layer the statement gets compiled? (like DB, JDBC, Java Apps.)”, most of them will answer JDBC. Since the answers are abstract, it could be interpreted in either way. Though the prepared statement concept are there for while very few provides in-depth answer. I did googling, the answers are scattered in various sites let me consolidate and give you a comprehensive view.

The prepared statement concept is not specific to Java, it is a database concept. Statement precompiling means: when you execute a SQL query, database server will prepare a execution plan before executing the actual query, this execution plan will be cached at database server for further execution.

The advantages of Prepared Statements are:

  1. As the execution plan get cached, performance will be better.
  2. It is a good way to code against SQL Injection as escapes the input values.
  3. When it comes to a Statement with no unbound variables, the database is free to optimize to its full extent. The individual query will be faster, but the down side is that you need to do the database compilation all the time, and this is worse than the benefit of the faster query.

Other than training purpose it is better to use PreparedStatement to get full benefits and close all loopholes.

I always expect “execution plan” jargon word when talking about prepared statements.

Delicious Digg reddit Facebook StumbleUpon

Advertisements

38 Responses to Back to Basics: Statement vs. Prepared Statement

  1. Muthu Velappan says:

    Venkat,

    I accept Prepared Statement is better w.r.t SQL Injection and repeated execution on same SQL with different values…

    But, I would also use plain Statement Object whenever i’m sure that current SQL is going to execute only once and SQL Injection worries are handled in other ways… I suggest using Statement Object here because there is only one network call where as Prepared Statement takes 2 one for compiling and another for execution… In this case how will a PreparedStatement is better than Statement Object?

    Regards,
    Muthu

  2. Venkat says:

    Muthu, thanks for your comments. At last busy person got time to read some articles too :)

    How do you say prepared statement makes two calls? If you have any reference please post.

    btw, prepared statement makes one call to database like Statement; but the execution plan get cached at database so the subsequent calls uses the same execution plan which makes the query execution faster.

  3. Muthu Velappan says:

    Venkat,

    Assume the following query, “Insert into Cities (name, population) Values (‘New York’, 500000 ); ”

    If I use prepare statement this would be the code

    String str = “Insert into Cities (name, population) Values (?, ? )”;
    Connection con = .getConnection();
    PreparedStatement p = con.prepareStatement( str);
    p.setString(‘New York’);
    p.setInt(500000);
    p.executeUpdate();

    If you look at these statements, there will be 2 Server calls. First one will be during “con.prepareStatement( str);” call, At this point of time the query gets compiled ( Execution plan generation/caching) on the server end. During “p.executeUpdate();” call a second call made to server to execute it.

    If we use Statement Object for these kind of trival queries, server call is made only once…

    I believe this will explained my point… Hope to hear your thoughts on this soon… :)

    Take Care

    Regards,
    Muthu

  4. Venkat says:

    Muthu, The query and values are not send to database in a separate round trip. The actual database communication happens only during executeUpdate() or executeQuery().

    To analyze the behaviour use the below code in has invalid table “User1”.
    PreparedStatement preparedStatement = connection.prepareStatement(“SELECT FirstName, LastName FROM User1”);
    System.out.println(“Statement prepared”);
    ResultSet resultSet = preparedStatement.executeQuery();
    System.out.println(“Statement executed”);

    After running the above code you will only see “Statement prepared” in console. As you mentioned if it makes calls to database during prepareStatment, that line should throw error for invalid table name.

  5. Muthu Velappan says:

    Venkat,

    Yes, You are right.. I could see the “statement prepared” in console…

    However, I’m 100% sure that there will be 2 n/w calls in prepared statement.. My example to explain that seems to be wrong. Please follow this link and click on Qn. No 25..

    http://www.theserverside.com/tt/talks/videos/JohnGoodson/dsl/interview.html

    You will see an explanation given by John Goodson on this topic.. I will also comeup with the proper example soon to explain my point asap…

    ~Muthu

  6. Muthu Velappan says:

    Venkat,

    I got the answer for printing “Statement Prepared” output in console even when the table doesn’t exist in DB..

    The reason is while executing statement

    PreparedStatement preparedStatement = connection.prepareStatement(”SELECT FirstName, LastName FROM User1″);

    At this point of a server call will happen and it just parses the syntax.. It will not check for the existence of table or column.. Since SQL syntax is correct, DB will not throw any error and hence process continues to next statement…

    If you have any doubt in this Copy the SQL statement and paste SQLSever Query Analyser and press CTRL+F5.. It will just parse the query and print of command executed successfully message, even when table1 doesn’t exist… If you press just F5 then only it will throw error…

    Hope this clarifies my point…

    ~Muthu

  7. Venkat says:

    Muthu, I am still not convinced that prepared statement makes two calls. However the below link shows some performance result of JDBC drivers’ on various scenarios.
    http://oreilly.com/catalog/jorajdbc/chapter/ch19.html

  8. Muthu Velappan says:

    Venkat, That article clearly shows what I’m talking about.. For Non-repeated inserts statements are much better option than prepared statements… You can see the time taken by P.Stmt is nearly 10 times higher that Stmt object…

    We all know that one of costliest job in JDBC is network calls. This additional time taken is only because of a additional n/w call rather than anything else…

    ~Muthu…

  9. vivek says:

    Thanks Muthu, But these all answer’s don’t remove my one confusion. As i think prepare statement executes only when we run java file while plain statement executes every time when we compile java file that makes it slow than prepared statement. Am i right.

  10. Muthu Velappan says:

    @Vivek, I don’t understand ur question. If u r asking whether Statement executes on every java compile, My answer is a big “NO”.. While compiling a source it is just getting transferred into byte code which has to be executed by ur JVM for execution. So there is no way that ur Code is making calls to DB. Compilation is just a conversion of ur source from human readable format to JVM readable format.

    ~Muthu

  11. partheeban says:

    I have a doubt,

    When the method ‘method()’ executes for the second time, will there be any benefit due to using preparedStatement ???

    Will the query gets compiled for the second time or it won’t, because it has been compiled already during the first call ?

    method(){

    PreparedStatement preparedStatement = connection.prepareStatement(”SELECT FirstName, LastName FROM User1″);

    preparedStatement.executeQuery();

    }

    }

  12. Venkat says:

    The query won’t get compiled on second time. So second time it will execute faster that is the benefit of using prepared statement.

  13. Lucas says:

    Just to reiterate… the prepareStatement method is used to pre-compile the sql query which does require one network call to the database.

    The executeQuery method sends the precompiled query to the database in a 2nd network call.

    A Statement does both of compile and execute in a single method call with a single network call.

    The early pre-compile does not save you much time if you are comparing a one-time sql execution, but if you intend to run the same query multiple times, the prepared statement is great and you should see much better performance when compared to running with the normal statement object.

  14. partheeban says:

    My doubt is
    will the query get recompiled while the below method is invoked second time ?

    method(){
    PreparedStatement preparedStatement = connection.prepareStatement(”SELECT FirstName, LastName FROM User1″);
    }

  15. Venkat says:

    Prepared statements are getting cached at database server level. The query will get compiled only once subsequently it will use cached execution plan.

  16. goose says:

    partheeban, the query will be recompiled again and again in your example.
    you should call the preapreStatement only once and repeat the call to executeQuery to benefit from the prepareStatement call.

  17. Tapshil says:

    I do agree with Venkat.

    I did a small experiment for statement vs prepared statement. I wrapped Oracle 10g driver with spy driver to log communication between my program and database.

    Here is my findings:

    1.) con.prepareStatement(“…”) does not make a database call. Along with correct and incorrect table name, I tried with right and wrong syntax and symantics of the SQL.
    Driver did not make a connection to DB a single time. The only time I found exception thrown while executing prepareStatement method was when my SQL was empty string. But even at this
    time DB call was not made. Exception was thrown by driver code.

    2.) With the prepared statement, connection to DB was made when the executeQuery() method was executed. The very first time when executeQuery() is executed, Oracle does following
    three steps:

    a.) Parsing: Parse the statement’s syntax and semantics.
    b.) Generating the execution plan: For each statement, generate an
    execution plan and store it in a shared memory area called the shared
    pool.
    c.) Executing: Execute the statement using the plan generated in step 2.

    And what I observed was when the SQL is executed with prepared statement very first time, query execution takes more time compared to very first time SQL is executed with java.sql.Statement.
    But with Preparedstatement you have to pay this ” time penatly” only for very first time (just like on the very first request time is taken by jsp compilation). Next onwards, when you execute prepareStatement and executeQuery methods, query execution would be much
    faster because now Oracle will do only query parsing and query execution based on already generated and store execution plan.

    3.) With java.sql.Statement, whenever you execute query with change in only parameter like emplyeeid, city etc, Oracle considers query as new and query would be “hard parsed” meaning query parsing,
    generation of execution plan and finally query execution would be done.

    In, enterprise application, the method, which has the code for query execution, would be executed multple times my multiple user requests. And so, we can gain performance benefit by using PreparedStatement.

  18. Venkat says:

    Thanks Tapshil, for sharing your findings.

  19. Jagan says:

    If we close the preparedtatement still the execution plan exist in shared pool. How it behaves in below scenario.

    method()
    {
    ps = connection.prepareStatement(sql)
    ps.set…
    ps.execute…
    ps.close()
    }

  20. Raghu says:

    @Jagan Based on the database server i.e. Oracle, Sybase etc the eviction policy for PreparedStatement in the pool is decided. This may be based on the current load or some LRU algorithm or heuristics particular to database implementation.

  21. Joe says:

    The Explanation is nice

  22. Madhav says:

    Thank you one and all for your valuable suggestions..

  23. Abhijit says:

    Hi Venkat,

    very nice article, thanks a lot.
    Even i was under impression that PreparedStatement does better than Statement till i came across one ppt released by Oracle saying this need not be necessarily true everytime…

    since there is considerable overhead involved for this…
    unfortunately I don’t have the link of that ppt; I will share it incase I get it…

    regards,
    abhijit

  24. If you are running a SQL statement once use Statement object to execute query using java program. if its running several time with same query along with different parameters then better option is PreparedStatement.

    With the Oracle Thin Driver we are experience 40 times higher execution time for one time SQL select query execution using PreparedStatement approach compare to Statement approach in an enterprise level application.

    So you can not blindly reply on PreparedStatement or Statement approach without knowing what you are doing

  25. If you are running a SQL statement once use Statement object to execute query using java program. if its running several time with same query along with different parameters then better option is PreparedStatement.

    With the Oracle Thin Driver we are experience 40 times higher execution time for one time SQL select query execution using PreparedStatement approach compare to Statement approach in an enterprise level application.

    So you can not blindly rely on PreparedStatement or Statement approaches without knowing what you are doing

  26. If you are running a SQL statement once use Statement object to execute query using java program. if its running several time with same query along with different parameters then better option is PreparedStatement.

    With the Oracle Thin Driver we are experience 40 times higher execution time for one time SQL select query execution using PreparedStatement approach compare to Statement approach in an enterprise level application.

    So you can not blindly rely on PreparedStatement or Statement approach without knowing what you are doing

  27. Avishek says:

    Let us consider this example, suppose we have a search screen which is taking user inputs for different parameters and at back end SQL is build. If one parameter is null and that one is not appended in WHERE clause. So, generated SQL is different for different search condiations. Here which one will give better performance, preparedStatement or Statement and why ?

  28. Anonymous says:

    Interesting take on this issue where he says you must never use statements and always use prepared or callable statements.

    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1993620575194

  29. Ramesh says:

    in an enterprise environment, i understand the pro’s of PreparedStatement, so, is Statement useless since it is always being parsed, doing execution plan and executed?

  30. Anonymous says:

    Yes, in my opinion you should never use Statement for any DML queries.

  31. Anonymous says:

    What if we explicitly close the PreparedStatement? Will it still be cashed in the database, and reused again to gain better performance?

    Will following code have any advantage than using Statement?

    pstmt = conn.prepareStatement(updatesql);
    pstmt.clearParameters();
    ps.setString(1, value);

    int rel = pstmt.executeUpdate();
    pstmt.close();

  32. Bala says:

    Hi Muthu

    As per Tapshil’s findings, PreparedStatement also hits the database once contradictory to your saying that it hits the DB twice. Do you agree with him or you still have different thoughts on this.

  33. D.Lak says:

    Thanks a lot for article.

  34. Rahul Gulabani says:

    Hi Tapshi,Muthu Thanks for this wonderful article .

    My question is why to use statement for single execution of sql query ,when for first time
    prepared statement and statement will give same result .

  35. puneet says:

    I have gone throught the jdbc driver api of SQLServer and i dont see any code there while making PreparedStatement object and setting values. there is only one network call when we gor for executeUpdate.

  36. Pingback: Error ORA-01000: Problema de punteros al hacer los INSERT con Java mediante JDBC | Apuntes de Programación

  37. Sujan Patnana says:

    Hi All,

    I have a different experience while using PreparedStatement and Statement.
    I my application we need to implement bulk insert of records.
    We are using MySql as database and the drivers are thin drivers.

    I wrote the method to insert data into database using Batch insert, Prepare statement and statement. Surprisingly I found that the statement implemented code less time that the other two.

    I am completely speechless. Is there any driver dependency or for MySql is there an issue.
    Can someone help me in understanding this issue.

    Thanks in advance…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: