MP 性能测试
import com.example.demo.model.User; import com.example.demo.service.impl.UserServiceImpl; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.ArrayList; import java.util.List; @SpringBootTest class UserControllerTest { // 最大循环次数 private static final int MAXCOUNT = 100000; @Autowired private UserServiceImpl userService; /** * MP 批量插入 */ @Test void saveBatch() { long stime = System.currentTimeMillis(); // 统计开始时间 List<User> list = new ArrayList<>(); for (int i = 0; i < MAXCOUNT; i++) { User user = new User(); user.setName("test:" + i); user.setPassword("123456"); list.add(user); } // MP 批量插入 userService.saveBatch(list); long etime = System.currentTimeMillis(); // 统计结束时间 System.out.println("执行时间:" + (etime - stime)); } }
以上程序的执行总共花费了 6088 毫秒,如下图所示:
从上述结果可知,使用 MP 的批量插入功能(插入数据 10W 条),它的性能比循环单次插入的性能提升了 14.5 倍。
MP 源码分析
从 MP 和循环单次插入的执行时间我们可以看出,使用 MP 并不是像有些朋友认为的那样,还是循环单次执行的,为了更清楚的说明此问题,我们查看了 MP 的源码。
MP 的核心实现代码是 saveBatch 方法,此方法的源码如下:
我们继续跟进 saveBatch 的重载方法:
从上述源码可以看出,MP 是将要执行的数据分成 N 份,每份 1000 条,每满 1000 条就会执行一次批量插入,所以它的性能要比循环单次插入的性能高很多。
那为什么要分批执行,而不是一次执行?别着急,当我们看了第 3 种实现方法之后我们就明白了。