2011-07-17 31 views
1

在許多查詢以下性能測試中,這個定時JDBC代碼需要500-600ms:ScalaQuery的query/queryNA比JDBC慢數倍?

 val ids = queryNA[String]("select id from account limit 1000").list 
     val stmt = session.conn.prepareStatement("select * from account where id = ?") 
     debug.time() { 
     for (id <- ids) { 
      stmt.setString(1, id) 
      stmt.executeQuery().next() 
     } 
     } 

然而,在使用時ScalaQuery的時間去> 2秒:

 val ids = queryNA[String]("select id from account limit 1000").list 
     implicit val gr = GetResult(r =>()) 
     val q = query[String,Unit]("select * from account where id = ?") 
     debug.time() { 
     for (id <- ids) { 
      q.first(id) 
     } 
     } 

與調試後,服務器日誌,原來這是由於PreparedStatements正在重複準備並且未被重用。

這實際上是我們在應用程序代碼中遇到的一個性能問題,所以我們想知道如果我們錯過了關於如何在ScalaQuery中正確地重複使用預準備語句的問題,或者如果下降到JDBC是建議的解決方法。

+0

如果這實際上是你正在運行的代碼,你可能想要確保的是,在你的第一個例子,熱點不只是扔掉你的循環,即它確實在執行1000次聲明。 – ig0774

+0

不會拋棄它 - executeQuery有副作用。 – Yang

回答

1

從scalaquery郵件列表中得到答案。這就是ScalaQuery的設計方式 - 它假設你是在下面提供語句池的東西:

如今ScalaQuery總是從Connection請求一個新的PreparedStatement。在早期版本中曾經有PreparedStatements的緩存,但我刪除了它,因爲這個問題已經有很好的解決方案。每個像樣的連接池都應該有一個PreparedStatement池的選項。如果您使用的是Java EE服務器,則應該有一個集成的連接池。對於獨立的應用程序,你可以使用像http://sourceforge.net/projects/c3p0/