2014-01-16 79 views
2

我一直在閱讀一些新的JDBC連接池(如Tomcat)不支持客戶端語句池。我已經讀過這是因爲大多數JDBC驅動程序都維護自己的語句緩存。但是,我沒有看到PostgreSQL發生這種情況。PostgreSQL和JDBC Prepared Statement Caching

我正確嗎?如果是這樣,我應該使用連接池,可以緩存準備好的語句,以獲得最佳的批量插入性能?

感謝

+1

要獲得最佳的批插入性能,您應該使用通過PgConnection訪問的「COPY」API。 AFAIK PgJDBC不維護「語句緩存」,我不確定這樣的事情是否有效,因爲每個會話都有自己獨立的一組服務器端準備語句。 PgJDBC的聲明批量目前是無用的,順便說一句,它只是單獨發送它們。 –

+0

感謝Craig,不幸的是它並不那麼簡單。該批處理來自JSON,並使用JPA將其解析爲具有各種關係的對象圖。很難對各種ID進行分類以創建文件來進行復制。 FWIW,如果您甚至準備了20份準備好的聲明,則只需準備一次聲明並重復使用它就有相當多的價值。 –

回答

0

Tomcat的JDBC連接池提供了StatementCache。我不知道如何使用它(使用JPA),但它承諾「在連接上緩存PreparedStatement和/或CallableStatement實例。」

但是對於插入批次,您可能不需要重新使用PreparedStatement:可以使用this example中所示的addBatch方法。奇怪的是,official documentation表示「這種方法不能在PreparedStatementCallableStatement上調用」。我猜你必須嘗試一下才能發現這是否屬實,正如Craig Ringer所說:「PgJDBC只是單獨發送它們」。

性能:在客戶端,服務器和驅動程序/網絡流量中出現故障。
數據庫服務器通常會了解對連接期望的查詢(這也是爲什麼通過連接池重新使用連接是個好主意)。我相信PostgreSQL數據庫服務器會在相同的查詢發生5次以上時開始記住來自連接的查詢。
如果驅動程序正確處理客戶端重新使用的PreparedStatement,驅動程序可以決定只發送新數據而不是整個查詢。這可以對插入語句產生顯着的積極性能影響(並且我相信其中包括用於SQL Server的JDBC驅動程序可以執行此操作)。
如果客戶端緩存PreparedStatement(例如,只有在創建它的連接關閉時語句才關閉),它將有助於不會一次又一次地執行相同的代碼(也來自驅動程序)。即更少的初始化時間和更少的垃圾收集

作爲例如用於替代Tomcat的JDBC連接池:我已經使用YapoolSimpleQueryCacheexample)與該發射了約15個不同的查詢有點服務器組件MySQL數據庫(和JDBC驅動程序)。在壓力/負載測試期間,我驚訝於池中所需的最大連接數量相對較少,這不會影響小型服務器組件的速度(即連接從池中借用相對較短的時間) 。所以,至少在某些情況下,客戶端語句的緩存可以有所作爲。

在一個側面節點上:如果你使用類似Hibernate的東西,Hibernate會爲你做很多優化(水下),並且很有可能已經爲你完成了(語句)高速緩存。

相關問題