From 38d796dc929927219e8d008e1957647b2bdc0ca5 Mon Sep 17 00:00:00 2001 From: qxo <49526356@qq.com> Date: Fri, 3 Nov 2023 22:05:31 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=20=E5=A2=9E=E5=8A=A0SQL=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E7=BC=93=E5=AD=98=EF=BC=8C=E4=BB=A5=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 之前除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未经测试* --- .../dialect/AbstractHelperDialect.java | 94 ++++++++++++++++++- .../dialect/helper/AS400Dialect.java | 5 + .../dialect/helper/CirroDataDialect.java | 4 + .../pagehelper/dialect/helper/Db2Dialect.java | 4 + .../dialect/helper/FirebirdDialect.java | 4 + .../dialect/helper/HsqldbDialect.java | 12 +++ .../dialect/helper/Oracle9iDialect.java | 4 + .../dialect/helper/OracleDialect.java | 4 + .../dialect/helper/SqlServer2012Dialect.java | 4 + .../dialect/helper/SqlServerDialect.java | 25 ++--- 10 files changed, 139 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/github/pagehelper/dialect/AbstractHelperDialect.java b/src/main/java/com/github/pagehelper/dialect/AbstractHelperDialect.java index e52736c7..c333e978 100644 --- a/src/main/java/com/github/pagehelper/dialect/AbstractHelperDialect.java +++ b/src/main/java/com/github/pagehelper/dialect/AbstractHelperDialect.java @@ -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; @@ -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 CACHE_COUNTSQL; + protected Cache CACHE_PAGESQL; + public static boolean cacheOnFlag = true;//临时性开关,为了方便切换,以验证缓存前后对比. + public static boolean tracingOn = false;//临时性开关 /** * 获取分页参数 * @@ -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 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 @@ -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"; } /** @@ -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); + } } /** diff --git a/src/main/java/com/github/pagehelper/dialect/helper/AS400Dialect.java b/src/main/java/com/github/pagehelper/dialect/helper/AS400Dialect.java index 6e07e473..ffef0bca 100644 --- a/src/main/java/com/github/pagehelper/dialect/helper/AS400Dialect.java +++ b/src/main/java/com/github/pagehelper/dialect/helper/AS400Dialect.java @@ -53,4 +53,9 @@ public Object processPageParameter(MappedStatement ms, Map 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; + } } diff --git a/src/main/java/com/github/pagehelper/dialect/helper/CirroDataDialect.java b/src/main/java/com/github/pagehelper/dialect/helper/CirroDataDialect.java index 59a882da..fd200d36 100644 --- a/src/main/java/com/github/pagehelper/dialect/helper/CirroDataDialect.java +++ b/src/main/java/com/github/pagehelper/dialect/helper/CirroDataDialect.java @@ -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; + } } diff --git a/src/main/java/com/github/pagehelper/dialect/helper/Db2Dialect.java b/src/main/java/com/github/pagehelper/dialect/helper/Db2Dialect.java index 4e6fc933..ad1e1ba4 100644 --- a/src/main/java/com/github/pagehelper/dialect/helper/Db2Dialect.java +++ b/src/main/java/com/github/pagehelper/dialect/helper/Db2Dialect.java @@ -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; + } } diff --git a/src/main/java/com/github/pagehelper/dialect/helper/FirebirdDialect.java b/src/main/java/com/github/pagehelper/dialect/helper/FirebirdDialect.java index fc35e632..d0c7dd3c 100644 --- a/src/main/java/com/github/pagehelper/dialect/helper/FirebirdDialect.java +++ b/src/main/java/com/github/pagehelper/dialect/helper/FirebirdDialect.java @@ -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; + } } diff --git a/src/main/java/com/github/pagehelper/dialect/helper/HsqldbDialect.java b/src/main/java/com/github/pagehelper/dialect/helper/HsqldbDialect.java index 9e78a24f..3a55b5a0 100644 --- a/src/main/java/com/github/pagehelper/dialect/helper/HsqldbDialect.java +++ b/src/main/java/com/github/pagehelper/dialect/helper/HsqldbDialect.java @@ -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; + } } diff --git a/src/main/java/com/github/pagehelper/dialect/helper/Oracle9iDialect.java b/src/main/java/com/github/pagehelper/dialect/helper/Oracle9iDialect.java index 0c4d4bff..7873f76f 100644 --- a/src/main/java/com/github/pagehelper/dialect/helper/Oracle9iDialect.java +++ b/src/main/java/com/github/pagehelper/dialect/helper/Oracle9iDialect.java @@ -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; + } } diff --git a/src/main/java/com/github/pagehelper/dialect/helper/OracleDialect.java b/src/main/java/com/github/pagehelper/dialect/helper/OracleDialect.java index 254016da..698c309f 100644 --- a/src/main/java/com/github/pagehelper/dialect/helper/OracleDialect.java +++ b/src/main/java/com/github/pagehelper/dialect/helper/OracleDialect.java @@ -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; + } } diff --git a/src/main/java/com/github/pagehelper/dialect/helper/SqlServer2012Dialect.java b/src/main/java/com/github/pagehelper/dialect/helper/SqlServer2012Dialect.java index c2e04d77..c0cd7bf4 100644 --- a/src/main/java/com/github/pagehelper/dialect/helper/SqlServer2012Dialect.java +++ b/src/main/java/com/github/pagehelper/dialect/helper/SqlServer2012Dialect.java @@ -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; + } } diff --git a/src/main/java/com/github/pagehelper/dialect/helper/SqlServerDialect.java b/src/main/java/com/github/pagehelper/dialect/helper/SqlServerDialect.java index eb62ff3a..3c117fd7 100644 --- a/src/main/java/com/github/pagehelper/dialect/helper/SqlServerDialect.java +++ b/src/main/java/com/github/pagehelper/dialect/helper/SqlServerDialect.java @@ -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; @@ -48,14 +47,12 @@ */ public class SqlServerDialect extends AbstractHelperDialect { protected SqlServerParser pageSql; - protected Cache CACHE_COUNTSQL; - protected Cache 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 { @@ -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; } @@ -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())); @@ -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); - } } }