MyBatis Plus大數(shù)據(jù)量查詢慢原因分析及解決
大數(shù)據(jù)量查詢慢的常見(jiàn)原因
MyBatis Plus 在處理大數(shù)據(jù)量查詢時(shí),性能瓶頸通常出現(xiàn)在數(shù)據(jù)庫(kù)連接、網(wǎng)絡(luò)傳輸、內(nèi)存消耗和結(jié)果集處理等方面。
常見(jiàn)問(wèn)題包括全表掃描、未合理使用分頁(yè)、ORM 映射開(kāi)銷過(guò)大等。
優(yōu)化方案
合理使用分頁(yè)查詢
MyBatis Plus 內(nèi)置分頁(yè)插件(PaginationInnerInterceptor),避免一次性加載全部數(shù)據(jù)。
配置示例:
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
查詢時(shí)通過(guò) Page 對(duì)象分頁(yè):
Page<User> page = new Page<>(1, 100); // 當(dāng)前頁(yè), 每頁(yè)條數(shù) userMapper.selectPage(page, null);
啟用流式查詢
通過(guò) @Options 注解啟用 JDBC 流式讀取,減少內(nèi)存占用:
@Select("SELECT * FROM large_table")
@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 1000)
@ResultType(User.class)
void selectLargeData(ResultHandler<User> handler);
使用游標(biāo)處理結(jié)果
結(jié)合 MyBatis 的 Cursor 逐行處理數(shù)據(jù):
try (Cursor<User> cursor = userMapper.selectCursor(null)) {
cursor.forEach(user -> {
// 單行處理邏輯
});
}
SQL 語(yǔ)句優(yōu)化
添加必要的索引,避免 SELECT *,只查詢必要字段。通過(guò) @SqlParser 注解過(guò)濾邏輯刪除等干擾:
@SqlParser(filter = true)
@Select("SELECT id, name FROM user WHERE status = 1")
List<User> selectActiveUsers();
批處理操作
插入/更新時(shí)使用 saveBatch 方法,通過(guò) rewriteBatchedStatements=true 參數(shù)提升批量性能:
List<User> userList = ... // 大數(shù)據(jù)集合 userService.saveBatch(userList, 1000); // 每批1000條
高級(jí)方案
多數(shù)據(jù)源與讀寫分離
通過(guò) @DS 注解將查詢路由到從庫(kù),減輕主庫(kù)壓力:
@DS("slave")
@Select("SELECT * FROM read_heavy_table")
List<Record> selectReadHeavyData();
結(jié)果集二次處理
在內(nèi)存充足的情況下,先通過(guò) LIMIT 分頁(yè)查詢 ID,再通過(guò) IN 查詢完整數(shù)據(jù):
-- 第一步:查詢ID范圍 SELECT id FROM large_table LIMIT 1000000, 1000; -- 第二步:精確獲取數(shù)據(jù) SELECT * FROM large_table WHERE id IN (1,2,3...);
配置調(diào)優(yōu)
在 application.yml 中調(diào)整連接池參數(shù):
spring:
datasource:
hikari:
maximum-pool-size: 20
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
監(jiān)控與診斷
啟用 p6spy 監(jiān)控實(shí)際執(zhí)行的 SQL,分析慢查詢?nèi)罩荆?/p>
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.9.1</version>
</dependency>
配置 spy.properties 記錄執(zhí)行時(shí)間:
appender=com.p6spy.engine.spy.appender.Slf4JLogger logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat customLogMessageFormat=%(executionTime) ms | %(category) | %(sql)
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot使用CommandLineRunner和ApplicationRunner執(zhí)行初始化業(yè)務(wù)方式
這篇文章主要介紹了SpringBoot使用CommandLineRunner和ApplicationRunner執(zhí)行初始化業(yè)務(wù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Nacos-SpringBoot框架啟動(dòng)不加載bootstrap.yml的解決
這篇文章主要介紹了Nacos-SpringBoot框架啟動(dòng)不加載bootstrap.yml的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
詳解SpringMVC?HandlerInterceptor攔截器的使用與參數(shù)
本文主要介紹了詳解SpringMVC?HandlerInterceptor攔截器的使用與參數(shù),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
Spring中事務(wù)用法示例及實(shí)現(xiàn)原理詳解
這篇文章主要給大家介紹了關(guān)于Spring中事務(wù)用法示例及實(shí)現(xiàn)原理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11
springmvc+shiro+maven 實(shí)現(xiàn)登錄認(rèn)證與權(quán)限授權(quán)管理
Shiro 是一個(gè) Apache 下的一開(kāi)源項(xiàng)目項(xiàng)目,旨在簡(jiǎn)化身份驗(yàn)證和授權(quán),下面通過(guò)實(shí)例代碼給大家分享springmvc+shiro+maven 實(shí)現(xiàn)登錄認(rèn)證與權(quán)限授權(quán)管理,感興趣的朋友一起看看吧2017-09-09
@RequestParam使用defaultValue屬性設(shè)置默認(rèn)值的操作
這篇文章主要介紹了@RequestParam使用defaultValue屬性設(shè)置默認(rèn)值的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02
BigDecimal divide除法除不盡報(bào)錯(cuò)的問(wèn)題及解決
這篇文章主要介紹了BigDecimal divide除法除不盡報(bào)錯(cuò)的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06

