【发布时间】:2010-08-27 11:56:37
【问题描述】:
我在这里似乎真的有一个大问题。我正在使用 MySQL 将词性标记的句子存储在表中。表格如下所示:
+------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+-------+
| idTitle | varchar(25) | NO | PRI | NULL | |
| idReview | int(10) unsigned | NO | PRI | NULL | |
| idSentence | int(10) unsigned | NO | PRI | NULL | |
| content | text | NO | | NULL | |
| POSInfo | text | YES | | NULL | |
+------------+------------------+------+-----+---------+-------+
这些是表上的索引:
+-----------------+------------+-----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------------+------------+-----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| reviewsentences | 0 | PRIMARY | 1 | idSentence | A | 23 | NULL | NULL | | BTREE | |
| reviewsentences | 0 | PRIMARY | 2 | idTitle | A | 32087 | NULL | NULL | | BTREE | |
| reviewsentences | 0 | PRIMARY | 3 | idReview | A | 2470720 | NULL | NULL | | BTREE | |
| reviewsentences | 1 | fk_ReviewSentences_Reviews1 | 1 | idTitle | A | 983 | NULL | NULL | | BTREE | |
| reviewsentences | 1 | fk_ReviewSentences_Reviews1 | 2 | idReview | A | 494144 | NULL | NULL | | BTREE | |
+-----------------+------------+-----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
我正在尝试阅读属于某个评论的评论句子,并将它们添加到评论对象中。我正在通过 JDBC 访问数据库,读取需要永远!!我说 2 分钟 26 行!这是我用来查询数据库的java代码:
public List<Review> fillupReviews(List<Review> reviews, boolean tagged){
try {
Statement stmt = dbConnection.createStatement() ;
for (Review review : reviews) {
ResultSet rs=null;
if(tagged==true){
rs = stmt.executeQuery("SELECT idSentence, POSInfo FROM reviewsentences WHERE idTitle="+review.getMovieID()+" and idReview="+review.getReviewID()+";") ;
}else{
rs = stmt.executeQuery("SELECT idSentence, content FROM reviewsentences WHERE idTitle="+review.getMovieID()+" and idReview="+review.getReviewID()+";") ;
}
while(rs.next()){
review.addTaggedSentence(rs.getInt(1),rs.getString(2));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return reviews;
}
如果我通过 MySQL Workbench 使用相同的查询访问同一个表,则需要 0.296 秒?所以我的猜测是一定有什么严重的错误!但我真的看不出哪里出了问题或改变什么来加速这个该死的事情。请问有人可以给我一个提示吗?
又是我,我终于找到了解决办法!叫做Prepared Statement!!
public List<Review> fillupReviews(List<Review> reviews, boolean tagged){
try {
PreparedStatement selectReview=null;
if(tagged==true){
selectReview = dbConnection.prepareStatement("SELECT idSentence, POSInfo FROM reviewsentences WHERE idTitle= ? AND idReview= ?;");
}else{
selectReview = dbConnection.prepareStatement("SELECT idSentence, Content FROM reviewsentences WHERE idTitle= ? AND idReview= ?;");
}
for (Review review : reviews) {
selectReview.setString(1, review.getMovieID());
selectReview.setInt(2, review.getReviewID());
ResultSet rs = selectReview.executeQuery();
while(rs.next()){
review.addTaggedSentence(rs.getInt(1),rs.getString(2));
}
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
return reviews;
}
现在这个漏洞运行起来就像地狱一样(几乎和 MySQL Workbench 一样快[0.3 秒])。我不完全明白为什么正常的陈述如此缓慢?有人对此有解释吗?
【问题讨论】:
-
一个旧的,但为了解释。 SGBD 只编译一次preparedStatement,然后将参数设置到正确的位置(不是在java 中,而是在sgbd 中)。一个简单的语句将在每次查询执行时编译。这个编译需要时间。
标签: java mysql performance jdbc