Skip to content

Commit

Permalink
refactor: 增加SQL解析缓存,以提升性能
Browse files Browse the repository at this point in the history
之前除SqlServerDialect外,其他Dialect之前没有sql解析缓存.

优化前项目中每次此plugin的SQL解析基本在7/8到几十毫秒之间,有时比sql本身数据库执行还慢时!

经分析这个慢原因是其依赖的jsqlparser本身解析就慢,且在4.5时有反向优化(采用线程池却没每次重新线程!)
```
jad net.sf.jsqlparser.parser.CCJSqlParserUtil parseStatement
```

测试发现jsqlparser 4.7和pagehelper不兼容, 4.6 和4.5有同样的问题

增加SQL解析缓存后,重复访问的耗时基本0.5毫秒以下

*需要说明的这次重构目前只在mysql下测试,其他Dialect未经测试*
  • Loading branch information
qxo committed Nov 10, 2023
1 parent c85631b commit 38d796d
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@

package com.github.pagehelper.dialect;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.pagehelper.Constant;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageRowBounds;
import com.github.pagehelper.cache.Cache;
import com.github.pagehelper.cache.CacheFactory;
import com.github.pagehelper.parser.OrderByParser;
import com.github.pagehelper.util.ExecutorUtil;
import com.github.pagehelper.util.MetaObjectUtil;
Expand All @@ -49,7 +54,16 @@
* @since 2016-12-04 14:32
*/
public abstract class AbstractHelperDialect extends AbstractDialect implements Constant {
/**
* Logger for this class.
*/
private static final Logger logger = LoggerFactory.getLogger(AbstractHelperDialect.class);

protected Cache<String, String> CACHE_COUNTSQL;
protected Cache<String, String> CACHE_PAGESQL;

public static boolean cacheOnFlag = true;//临时性开关,为了方便切换,以验证缓存前后对比.
public static boolean tracingOn = false;//临时性开关
/**
* 获取分页参数
*
Expand All @@ -74,12 +88,45 @@ public boolean beforeCount(MappedStatement ms, Object parameterObject, RowBounds

@Override
public String getCountSql(MappedStatement ms, BoundSql boundSql, Object parameterObject, RowBounds rowBounds, CacheKey countKey) {
final long startTime = tracingOn || logger.isDebugEnabled() ? System.nanoTime() : 0;
if (startTime > 0) {
logger.info("getCountSql start ...");
}
Page<Object> page = getLocalPage();
String countColumn = page.getCountColumn();
final String sql = boundSql.getSql();
final String countSqlKey;
String cachedSql;
final boolean cacheOn = cacheOnFlag && CACHE_COUNTSQL != null;
if (StringUtil.isNotEmpty(countColumn)) {
return countSqlParser.getSmartCountSql(boundSql.getSql(), countColumn);
countSqlKey = sql + countColumn;
cachedSql = cacheOn ? CACHE_COUNTSQL.get(countSqlKey) : null;
if (cachedSql != null) {
logCountSqlEnd(startTime);
return cachedSql;
}
cachedSql = countSqlParser.getSmartCountSql(sql, countColumn);
} else {
countSqlKey = sql;
cachedSql = cacheOn ? CACHE_COUNTSQL.get(countSqlKey) : null;
if (cachedSql != null) {
logCountSqlEnd(startTime);
return cachedSql;
}
cachedSql = countSqlParser.getSmartCountSql(sql);
}
if (cacheOn) {
CACHE_COUNTSQL.put(countSqlKey, cachedSql);
}
logCountSqlEnd(startTime);
return cachedSql;
}

private void logCountSqlEnd(final long startTime) {
if (startTime > 0) {
final long time = System.nanoTime() - startTime;
logger.info("getCountSql(cacheOn={}) end: {}", cacheOnFlag, Double.toString(time == 0 ? 0 : time/1000000d));
}
return countSqlParser.getSmartCountSql(boundSql.getSql());
}

@Override
Expand Down Expand Up @@ -186,14 +233,43 @@ public String getPageSql(MappedStatement ms, BoundSql boundSql, Object parameter
Page page = getLocalPage();
//支持 order by
String orderBy = page.getOrderBy();
String cacheSqlKey = getPageCacheSqlKey(page, sql);
final boolean cacheOn = cacheOnFlag && CACHE_PAGESQL != null;
final boolean orderByOnly = page.isOrderByOnly();
if (StringUtil.isNotEmpty(orderBy)) {
if (cacheOn) {
cacheSqlKey += orderBy;
if (orderByOnly) {
cacheSqlKey += "-orderByOnly";
}
}
pageKey.update(orderBy);
sql = OrderByParser.converToOrderBySql(sql, orderBy, jSqlParser);
sql = cacheOn ? CACHE_PAGESQL.get(cacheSqlKey) : null;
if (sql == null) {
sql = OrderByParser.converToOrderBySql(sql, orderBy, jSqlParser);
if (cacheOn && orderByOnly) {
CACHE_PAGESQL.put(cacheSqlKey, sql);
}
}
}
if (page.isOrderByOnly()) {
if (orderByOnly) {
return sql;
}
return getPageSql(sql, page, pageKey);
String pageSql = cacheOn ? CACHE_PAGESQL.get(cacheSqlKey) : null;
if (pageSql == null) {
pageSql = getPageSql(sql, page, pageKey);
if (cacheOn) {
CACHE_PAGESQL.put(cacheSqlKey, pageSql);
}
}
return pageSql;
}

protected String getPageCacheSqlKey(Page page, String sql) {
if (page.getStartRow() == 0) {
return sql;
}
return sql + "-1";
}

/**
Expand Down Expand Up @@ -232,6 +308,14 @@ public void afterAll() {
@Override
public void setProperties(Properties properties) {
super.setProperties(properties);
final String sqlCacheClass = properties.getProperty("sqlCacheClass");
if (StringUtil.isNotEmpty(sqlCacheClass) && !sqlCacheClass.equalsIgnoreCase("false")) {
CACHE_COUNTSQL = CacheFactory.createCache(sqlCacheClass, "count", properties);
CACHE_PAGESQL = CacheFactory.createCache(sqlCacheClass, "page", properties);
} else if (!"false".equalsIgnoreCase(sqlCacheClass)){
CACHE_COUNTSQL = CacheFactory.createCache(null, "count", properties);
CACHE_PAGESQL = CacheFactory.createCache(null, "page", properties);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,9 @@ public Object processPageParameter(MappedStatement ms, Map<String, Object> param
public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sql + " OFFSET ? ROWS FETCH FIRST ? ROWS ONLY";
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,8 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,8 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,8 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,16 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
}
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
String cacheKey = sql;
if (page.getPageSize() > 0) {
cacheKey += "-p";
}
if (page.getStartRow() > 0) {
cacheKey += "-s";
}
return cacheKey;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,8 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,8 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,8 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
package com.github.pagehelper.dialect.helper;

import com.github.pagehelper.Page;
import com.github.pagehelper.cache.Cache;
import com.github.pagehelper.cache.CacheFactory;
import com.github.pagehelper.PageProperties;
import com.github.pagehelper.dialect.AbstractHelperDialect;
import com.github.pagehelper.dialect.ReplaceSql;
import com.github.pagehelper.dialect.replace.RegexWithNolockReplaceSql;
Expand All @@ -48,14 +47,12 @@
*/
public class SqlServerDialect extends AbstractHelperDialect {
protected SqlServerParser pageSql;
protected Cache<String, String> CACHE_COUNTSQL;
protected Cache<String, String> CACHE_PAGESQL;
protected ReplaceSql replaceSql;

@Override
public String getCountSql(MappedStatement ms, BoundSql boundSql, Object parameterObject, RowBounds rowBounds, CacheKey countKey) {
String sql = boundSql.getSql();
String cacheSql = CACHE_COUNTSQL.get(sql);
String cacheSql = CACHE_COUNTSQL == null ? null : CACHE_COUNTSQL.get(sql);
if (cacheSql != null) {
return cacheSql;
} else {
Expand All @@ -64,7 +61,9 @@ public String getCountSql(MappedStatement ms, BoundSql boundSql, Object paramete
cacheSql = replaceSql.replace(cacheSql);
cacheSql = countSqlParser.getSmartCountSql(cacheSql);
cacheSql = replaceSql.restore(cacheSql);
CACHE_COUNTSQL.put(sql, cacheSql);
if (CACHE_COUNTSQL != null) {
CACHE_COUNTSQL.put(sql, cacheSql);
}
return cacheSql;
}

Expand All @@ -78,13 +77,15 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
//处理pageKey
pageKey.update(page.getStartRow());
pageKey.update(page.getPageSize());
String cacheSql = CACHE_PAGESQL.get(sql);
String cacheSql = CACHE_PAGESQL == null ? null : CACHE_PAGESQL.get(sql);
if (cacheSql == null) {
cacheSql = sql;
cacheSql = replaceSql.replace(cacheSql);
cacheSql = pageSql.convertToPageSql(cacheSql, null, null);
cacheSql = replaceSql.restore(cacheSql);
CACHE_PAGESQL.put(sql, cacheSql);
if (CACHE_PAGESQL != null) {
CACHE_PAGESQL.put(sql, cacheSql);
}
}
cacheSql = cacheSql.replace(String.valueOf(Long.MIN_VALUE), String.valueOf(page.getStartRow()));
cacheSql = cacheSql.replace(String.valueOf(Long.MAX_VALUE), String.valueOf(page.getPageSize()));
Expand Down Expand Up @@ -125,13 +126,5 @@ public void setProperties(Properties properties) {
} else {
this.replaceSql = ClassUtil.newInstance(replaceSql, properties);
}
String sqlCacheClass = properties.getProperty("sqlCacheClass");
if (StringUtil.isNotEmpty(sqlCacheClass) && !sqlCacheClass.equalsIgnoreCase("false")) {
CACHE_COUNTSQL = CacheFactory.createCache(sqlCacheClass, "count", properties);
CACHE_PAGESQL = CacheFactory.createCache(sqlCacheClass, "page", properties);
} else {
CACHE_COUNTSQL = CacheFactory.createCache(null, "count", properties);
CACHE_PAGESQL = CacheFactory.createCache(null, "page", properties);
}
}
}

0 comments on commit 38d796d

Please sign in to comment.