简体   繁体   English

MySQL查询结果非常慢

[英]MySQL Query result is very slow

I am executing a simple query on a small table 我正在一个小桌子上执行一个简单的查询

SELECT * FROM SYSTEM

System table only has three columns(Id, Name, Progress) and 1300 rows. 系统表只有三列(Id,Name,Progress)和1300行。

My code for getting the data is: 我获取数据的代码是:

try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            conn = (Connection) DriverManager.getConnection(
                    "jdbc:mysql://192.168.0.107:3306/my_database",
                    username.getText(), password.getText());
            String query = "select * from system";
            stmt = (Statement) conn.createStatement();
            rs = (ResultSet) stmt.executeQuery(query);
            while (rs.next()) {
                tableModel.addRow(new Object[] { rs.getInt("Number"),
                        rs.getString("Name"), rs.getFloat("Progress") });
            }
        } catch (Exception e) {
            // some other code
        }`

This code takes around 15 seconds to display the date in my JTable, while if I execute the query in phpmyadmin it takes less than one second. 此代码在我的JTable中显示日期大约需要15秒,而如果我在phpmyadmin中执行查询则需要不到一秒钟。

The issue here was likely the 这里的问题很可能是

while (rs.next()) { tableModel.addRow(...)

Each call to addRow() means a "Notification of the row being added will be generated." 每次调用addRow()意味着“将生成正在添加的行的通知”。

This notification of the Listener (s) means quite some overhead. 这个Listener通知意味着一些开销。 Likely, each call indirectly involves a call to invalidate the GUI's state, and more, because the table will have to be redrawn after it changed. 可能,每次调用间接涉及调用invalidate GUI的状态invalidate ,以及更多,因为该表必须在更改后重绘。 Doing that 1300x in ~15s means 100 of those calls per second, which is quite reasonable. 在15秒内完成1300x意味着每秒100次这样的呼叫,这是非常合理的。 The OP should probably look for a way to first gather all data and then update the table model only once with all the data. OP应该寻找一种方法来首先收集所有数据,然后仅使用所有数据更新表模型一次 This may mean having to implement his own variation of DefaultTableModel or AbstractTableModel . 这可能意味着必须实现自己的DefaultTableModelAbstractTableModel变体。

I would use a PreparedStatment and I would increase the default ResultSet fetchSize , and I would limit the query to the three columns ( note id != Number ) - 我会使用PreparedStatment ,我会增加默认的ResultSet fetchSize ,我会将查询限制为三列( 注意 id != Number ) -

String query = "select Number, Name, Progress from system";
stmt = conn.prepareStatement(query);
rs = stmt.executeQuery();
rs.setFetchSize(250);

Finally, establishing a Connection like that is probably the wrong way to go for performance. 最后,建立这样的连接可能是获得性能的错误方法。 You should look for a Connection pool like BoneCP or c3p0 or HikariCP . 您应该寻找像BoneCPc3p0HikariCP这样的连接池。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM