CH18-性能优化
动态条件
通过传入参数动态组装条件语句时,条件可能均为空,常见做法是使用 where 1=1
作为占位符,避免所有条件为空时语法错误:
<select id="getFruitInfo" resultType="Fruit">
SELECT * FROM Fruit
WHERE 1=1
<if test="id!= null">
and id = #{id}
</if>
<if test="name!= null">
and name = #{name}
</if>
</select>
如果 id 和 name 均为 null,则整个语句变成了:
SELECT * FROM Fruit WHERE 1=1
这时数据库就无法使用索引等查询优化策略,被迫对每行数据进行扫描,如果表很大,则性能消耗巨大,推荐的做法是使用 WHERE
标签:
<select id="getFruitInfo" resultType="Fruit">
SELECT * FROM Fruit
<WHERE>
<if test="id!= null">
id = #{id}
</if>
<if test="name!= null">
and name = #{name}
</if>
</WHERE>
</select>
where 元素知道只有在一个以上的 if 条件有值的情况下才去插入 “where” 子句,且最后的内容如果是 “AND” 或 “OR” 开头的,where 元素也能识别并将它们去除。
批量插入
在使用 foreach 执行批量插入时,如果条目很多,会生成一个很长的 sql 语句,然后再使用实际的条目数据带入,构造出要执行的 sql,这个过程会很慢。
推荐的做法是使用 BATCH 模式执行批量插入:
@Service
public class PersonService {
@Autowired
private SqlSessionFactory sqlSessionFactory;
public void insertPersions(List<Person> persons) {
try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
PersonMapper mapper = session.getMapper(PersonMapper.class);
for (Person person : persons) {
mapper.insert(person);
}
session.commit();
session.clearCache();
}
}
}
WHERE IN foreach
<select id="getUserInfo" resultType="com.test.UserList">
SELECT age FROM user
WHERE
<if test="userName!= null and userName.size() >0">
user_name IN
<foreach collection="userName" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</if>
</select>
但列表可能为空,所以总是在调用之前判空。或者有些同学会以如下方式兼容:
<select id="getUserInfo" resultType="com.test.UserList">
SELECT age FROM user
WHERE
<if test="userName!= null and userName.size() >0">
user_name IN
<foreach collection="userName" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</if>
<if test="userName!= null and userName.size() ==0">
1=2
</if>
<if test="userName!= null and userName.size() ==1">
user_name = #{users[0].userName}
</if>
</select>
基于 IN 的性能问题,可以将 IN 改为 JOIN。
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.