需求
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 table
WHERE 查询条件
LIMIT 页码, 条数;
</select>
<!-- 获取总条数 -->
<select id="getCount" resultType="int">
SELECT FOUND_ROWS();
</select>