簡體   English   中英

JDBC和MySQL讀取性能

[英]JDBC & MySQL read performance

我這里似乎有一個很大的問題。 我正在使用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訪問數據庫,讀取將永遠! 我正在談論26行2分鍾! 這是我用來查詢數據庫的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;
}

如果我通過My​​SQL Workbench使用相同的查詢訪問同一個表,它需要0.296秒? 所以我的猜測是必須有嚴重的錯誤! 但是我真的看不出出了什么問題或者要改變什么來加快這個問題。 請有人能給我一個提示嗎?

這是我,我終於找到了解決方案! 被稱為准備聲明!! < - 誰會猜到的?? 這是代碼:

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秒])。 我不完全得到的是為什么正常陳述如此緩慢? 有人對此有解釋嗎?

首先,你只是為這個方法調用計時嗎?

你在哪里獲得數據庫連接,你是否只計算執行查詢的時間或獲得連接的時間?

你在使用連接池嗎? 也許那里有一個問題,嘗試首先獲得一個新連接以縮小范圍。

無論它不應該花這么長時間,有些東西是錯的,我懷疑你的連接設置可能是java找到mysql的方式(是本地的,你使用dns等)。

我也會使用預備語句,它們更安全,性能更好。

你還在用什么驅動程序?

如果它是本地MySQL服務器,那么我會嘗試評論MySQL提取,並用虛擬代碼替換以檢查代碼的性能(不要忘記使用你的GetMovieId()等東西)。

注釋掉review.addTaggedSentence(rs.getInt(1),rs.getString(2)); 它還需要那么多時間嗎?

您沒有關閉ResultSet,您需要在while(rs.next())完成后執行rs.close()

打印出您在Java中運行的實際SQL - 您是否100%確定它與您在MySQL工作台中運行的查詢相同?

您還在for (Review review : reviews)中運行查詢,那么運行了多少查詢?

你沒告訴我們什么需要2.36分鍾。 所以 - 在你的java應用程序中配置文件或做一些簡單的System.out.println(),這樣你就可以確定你實際運行的是什么SQL,以及它們中有多少運行。

您似乎有2470720條評論。 與在Mysql Workbench中本地運行相比,遠程(在您的代碼中)運行肯定需要更長的時間來查詢,返回和傳輸那么多值。

Mysql工作台可能會獲取結果的計數並分頁它給你的東西 - 只在必要時返回結果; 此外,您的工作台可能會在連接時啟用壓縮,而JDBC則不會,從而創建更快的連接。

首先。 您能否詳細說明代碼的哪一部分需要2m ++。 它是在聲明stmt.executeQuery(String)還是其他部分?

我自己碰巧遇到了一個大型DBMS的問題。 但我的數據大於150K。 不幸的是,我沒有針對您的問題提供現成的解決方案。 但是我做了一些足跡。

  1. 我試圖從驅動程序切換到驅動程序。 請記住,某些驅動程序可能會運行得更快,但它會要求您犧牲可移植性。
  2. 我試圖從硬編碼連接切換到連接池。 不幸的是,它並沒有真正的幫助。
  3. 我盡量不在VARCHAR字段上使用“WHERE”子句。
  4. 我試圖索引一些我經常“在哪里”的字段
  5. 我試圖使用Prepared Statement來確保DBMS不會重新哈希相同的查詢。

還有其他的東西,但我認為它們是DMBS特定的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM