2012-08-06 73 views
0

我正在讀取來自Access數據庫中的三個表的大量數據〜200萬行,可能是100MB的文本。 我用下面的SELECT語句:我的SQL PreparedStatement有什麼問題?

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=" + databaseLocation + databaseName +";selectMethod=cursor; READONLY=true; TYPE=FASTLOAD"; 

con = DriverManager.getConnection(url); 

String SQL = "SELECT ADDRESS_MODEL.ADDR_LINE_1, ADDRESS_MODEL.ADDR_LINE_2, LOCALITIES.NAME, ADDRESS_MODEL.SECONDARY_LOCALITY, ADDRESS_MODEL.POST_TOWN, ADDRESS_MODEL.COUNTY, BUILDINGS.ED_ID FROM (ADDRESS_MODEL LEFT JOIN BUILDINGS ON ADDRESS_MODEL.BUILDING_ID = BUILDINGS.BUILDING_ID) LEFT JOIN LOCALITIES ON BUILDINGS.LOCALITY_ID = LOCALITIES.LOCALITY_ID WHERE BUILDINGS.COUNTY_ID = " + county_ID; 

Statement stmt = con.createStatement(); 
ResultSet result = stmt.executeQuery(SQL); 

這是服用一段時間(約2分鐘),所以我就開始尋找使其更快。 我讀了關於準備好的陳述,並決定嘗試做一個。繼各種教程後,我把它放在一起:

String SQL = "SELECT ADDRESS_MODEL.ADDR_LINE_1, ADDRESS_MODEL.ADDR_LINE_2, LOCALITIES.NAME, ADDRESS_MODEL.SECONDARY_LOCALITY, ADDRESS_MODEL.POST_TOWN, ADDRESS_MODEL.COUNTY, BUILDINGS.ED_ID FROM (ADDRESS_MODEL LEFT JOIN BUILDINGS ON ADDRESS_MODEL.BUILDING_ID = BUILDINGS.BUILDING_ID) LEFT JOIN LOCALITIES ON BUILDINGS.LOCALITY_ID = LOCALITIES.LOCALITY_ID WHERE BUILDINGS.COUNTY_ID = ?"; 

PreparedStatement prest = con.prepareStatement(SQL); 
prest.setString(1, county_ID); 

ResultSet result = prest.executeQuery(); 

它仍然有效,但現在它需要超過15分鐘。我有一個很好的谷歌,但我似乎無法發現我做錯了什麼。準備好的陳述不適合我的特殊問題嗎?

+2

多久,如果你直接對數據庫運行的查詢採取的主要論點? – JamesB 2012-08-06 19:45:31

+0

我沒有具體的建議,但我建議您調查獲得更好的JDBC驅動程序。 – 2012-08-06 19:50:12

+0

@JamesB幾乎幾乎沒有時間。不到一秒鐘。 – Russell 2012-08-06 19:50:55

回答

1

當您想要多次執行相同的查詢時,使用PreparedStatement的主要性能收益會得到提示。數據庫在語句準備好時構造查詢,然後在每次執行語句時重新使用它以避免開銷。如果您只執行一次查詢,那麼使用PreparedStatement可能不會看到任何性能改進。

使用PreparedStatement的是要防止SQL注入

+0

有趣。看來我誤解了。我認爲每次你檢索一個記錄時,「查詢的執行」都是這樣,在這種情況下,記錄非常多次。如果實際上這只是查詢的一次執行,那麼我可以看到它爲什麼沒有更快。 – Russell 2012-08-06 19:54:20

+0

@Russell如果你在一個循環中多次執行它,你希望在循環之外創建PreparedStatement,然後在循環內調用'PreparedStatement.setString()'和'PreparedStatement.executeQuery()'作爲顯示[here](http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html)。這是你在做什麼? – Edd 2012-08-06 20:02:05

+0

@Edd恐怕我覺得我誤解了你使用PreparedStatements的原因。我只執行25次查詢。我認爲這是讀取的大量記錄會加快,但似乎沒有。 – Russell 2012-08-06 20:09:35