簡體   English   中英

MySQL選擇JDBC的性能問題

[英]MySQL select performance issue with JDBC

使用mysql-connector v5.1.30運行本地Java應用程序時,MySQL(v5.5)出現性能問題

我有2個分別稱為A和B的表。

PreparedStatement stmtA = conn.prepareStatement("select x, y, z, u, v, w from A");
PreparedStatement stmtB = conn.prepareStatement("select val from B where something = ?");
ResultSet result = stmtA.executeQuery();
while ( resultA.next() ){
    // do something with result row
    if (some condition) { // true approx. 80% of the time
        ResultSet resultB = stmtB.executeQuery(some_value_from_resultA);
        // do something with result row  
        resultB.close();
    }
}
stmtA.close();

問題在於,這每次大約需要12分鍾才能完成。 以下是一些相關信息:

  • mysqld進程在12分鍾的時間內使用95-99%的CPU
  • Java進程在12分鍾內使用1-4%CPU
  • 這兩個進程的內存使用量可以忽略不計
  • 表A具有65,000個記錄,18列(除了ID以外的所有VARCHAR),並使用MYISAM
  • 表B具有51,000條記錄,4列(3個INT和1個VARCHAR),並使用MYISAM
  • 我要查詢的表B列上沒有索引/鍵
  • 我正在使用Core i5和4GB RAM運行Ubuntu 12.04

除了mysql進程的CPU使用率非常瘋狂之外,我認為還有一個問題是因為該應用程序具有其他功能,可以針對不同的數據庫表運行幾乎相同的方法。 該表具有與表A相似的列數(也使用MYISAM),但是最大的不同是這里沒有表B。 因此,它的工作原理與上述相同,但是不必在迭代第一個表的行時查詢第二個表。

該另一個表具有4,500行,並且迭代花費不到1秒的時間。

因此,似乎是表B的嵌套查詢引起了問題,但我不確定。 我對MySQL的經驗有限。 如果您需要更多信息,請詢問。

您可能需要預加載或緩存在表B上運行的查詢的結果。由於表B沒有很多記錄,因此您可以負擔得起將其加載到映射中。

您有兩種選擇:

  1. 預加載整個B表並創建內容(鍵)和val(值)的映射。 然后訪問該映射,而不是運行0.8 * 65000查詢。 如果something具有許多唯一值,並且您的B查詢搜索了許多唯一值,那將是最有效的。
  2. 將每個查詢的結果存儲在映射中的B上,並在運行這些查詢之前檢查該映射。 兩次加載相同的數據沒有意義。 如果僅在B查詢中使用something值的一小部分,則在內存方面將更為有效。

在表B上添加索引也有幫助。

暫無
暫無

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

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