2

我正在使用 Spring jdbcTemplate 在我的 java 应用程序中运行 MySQL 查询。这是我的功能:

public static ArrayList<Map<String, Object>> query(String q) throws Exception {

    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

    @SuppressWarnings("unchecked")
    List<Map<String, Object>> result = jdbcTemplate.queryForList(q);

    return (ArrayList<Map<String, Object>>) result;

}

在这种特殊情况下,我将这个查询传递给函数:

"SELECT * FROM test WHERE name IN('string1', 'string2', 'string3', ...)";

test只有 6 列,字符串IN从几个符号到 100 个符号不等。运行查询jdbcTemplate.queryForList()需要280 毫秒。注意:运行需要 280 毫秒jdbcTemplate.queryForList(),而不是整个函数query。当我在 MySQL 客户端 (HeidiSQL) 上运行完全相同的查询时,它只需要16 毫秒更新:海蒂保持开放连接,所以这不是一个公平的比较。

jdbcTemplate.queryForList()问题:与在 MySQL 客户端上运行的相同查询相比,为什么速度如此之慢?我纯粹出于方便的原因使用它,它可以检索ArrayList<Map<String, Object>>我需要的结果。我可以做些什么来加快速度,还是应该把jdbcTemplate所有东西放在一起并使用其他东西?

更新:好的,所以我将函数从 jdbcTemplate 更改为使用普通 jdbc。这就是那个可憎的样子。这就是我首先选择 jdbcTemplate 的原因。现在运行相同的查询需要200 毫秒- 略有改进,但仍然太慢......

public static ArrayList<Map<String,Object>> query(String Full_Command) {

    try {

        String URL = "jdbc:mysql://localhost/dbname";
        String USER = "root";
        String PASS = "";
        java.sql.Connection Con = DriverManager.getConnection(URL, USER, PASS);

        //create statement
        Statement Stm = null;
        //Stm = Con.createStatement();
        Stm = (Statement) Con.createStatement();

        //query
        ResultSet Result = null;
        boolean Returning_Rows = Stm.execute(Full_Command);
        if (Returning_Rows) {
            Result = Stm.getResultSet();
        } else {
            return new ArrayList<Map<String,Object>>();
        }

        //get metadata
        ResultSetMetaData Meta = null;
        Meta = Result.getMetaData();

        //get column names
        int Col_Count = Meta.getColumnCount();
        ArrayList<String> Cols = new ArrayList<String>();
        for (int Index=1; Index<=Col_Count; Index++) {
            Cols.add(Meta.getColumnName(Index));
        }

        //fetch out rows
        ArrayList<Map<String, Object>> Rows = new ArrayList<Map<String,Object>>();

        while (Result.next()) {
            HashMap<String,Object> Row = new HashMap<String,Object>();
            for (String Col_Name:Cols) {
                Object Val = Result.getObject(Col_Name);
                Row.put(Col_Name,Val);
            }
            Rows.add(Row);
        }

        //close statement
        Stm.close();

        //pass back rows
        return Rows;

    } catch (Exception Ex) {

        System.out.print(Ex.getMessage());
        return new ArrayList<Map<String,Object>>();

    }

}

UPDATE2:我没有将 JDBC 函数分解为执行时间,这一行是瓶颈,每次大约需要 190 毫秒:

java.sql.Connection Con = DriverManager.getConnection(URL, USER, PASS);

任何意见?

4

4 回答 4

2

尝试增加获取大小(JdbcTemplate.setFetchSize),这可能是瓶颈。

于 2013-08-06T11:26:24.713 回答
2

我认为您无法获得比原始 jdbc 调用更快的速度。当您说您可以使用 sql 客户端更快地获取它时,它是第一次尝试吗?客户端和数据库可以缓存结果,因此请检查创建会话后从您的 sql 客户端运行的第一个查询的时间。还发布 java 日志,这将有助于查看时间花在哪里。

于 2013-08-06T12:07:58.927 回答
2

这不是 JdbcTemplate 的错。原因如下:

首先,您必须减少建立连接的开销。此开销可能高达 500 毫秒。这是正常的。

其次,当您在 MySQL 客户端上运行查询时,您是否在运行程序后立即运行它?因为查询会被缓存……即使在磁盘 I/O 级别。因此,如果您两次运行相同的查询,由于缓存,第二次运行速度会更快。

第三,您是否在为该列编制索引name

第四,如果连接开销对您来说真的很重要,您可以考虑保存连接甚至连接池。

于 2013-08-06T13:53:59.270 回答
0

可能是建立您的第一个数据库连接的开销。在您确定已经建立连接之后尝试对性能进行基准测试。

这东西应该慢,收益就在那里!

于 2013-08-06T12:06:18.257 回答