需求
ReturnResult result = new ReturnResult();
try {List<Map> forList = (List<Map>) dao.findForList("Mapper.getList", map);int count = (int) dao.findForObject("Mapper.getCount", map);result.setData(forList);result.setCode(0);result.setFlag(true);result.setCount(count);
} catch (Exception e) {result.setCode(0);result.setMessage(e.getMessage());result.setFlag(false);
}
return result;
以上代码运行速度缓慢,当数据量过大时,运行时间超过20秒。优化运行速度。
思路
这段代码看起来逻辑非常简通过dao调用了两次Mapper中的SQL语句,第一次通过map将条件及页码传入,查询出对应页码的数据。
第二次将sql中的limit去除,实现查询全部数据。
首先使用explain
查看语句是否走索引。经测试sql有部分条件没有索引,将索引添加完毕后速度有了质的提高。
但查看sql语句,发现两段调用sql几乎相同,运行时间也相同,java程序顺序执行,及执行时间翻倍。使用SQL_CALC_FOUND_ROWS
和 FOUND_ROWS()
可以解决该问题。
使用及完整代码
利用 SQL_CALC_FOUND_ROWS
和 FOUND_ROWS()
关键字。以下是具体的 SQL 查询方法:
-
使用
SQL_CALC_FOUND_ROWS
SQL 查询:SELECT SQL_CALC_FOUND_ROWS * FROM table WHERE 查询条件 LIMIT 页码, 条数;
·*·代表需要查询出的字段。
2. 使用FOUND_ROWS()
获取总条数:
SELECT FOUND_ROWS();
SQL_CALC_FOUND_ROWS
会计算符合条件的总行数,而不受 LIMIT
的影响。FOUND_ROWS()
会返回上一个查询的结果总数。
Java 代码实现
ReturnResult result = new ReturnResult();
try {// 获取分页数据List<Map> forList = (List<Map>) dao.findForList("Mapper.getList", map);// 获取总条数int count = (int) dao.findForObject("Mapper.getCount");result.setData(forList);result.setCode(0);result.setFlag(true);result.setCount(count);
} catch (Exception e) {result.setCode(0);result.setMessage(e.getMessage());result.setFlag(false);
}
return result;
Mapper XML
<!-- 获取分页数据并计算总条数 -->
<select id="getList" parameterType="map" resultType="map">SELECT SQL_CALC_FOUND_ROWS *FROM tableWHERE 查询条件LIMIT 页码, 条数;
</select><!-- 获取总条数 -->
<select id="getCount" resultType="int">SELECT FOUND_ROWS();
</select>