Эх сурвалжийг харах

计量计算查询性能提升

learshaw 1 сар өмнө
parent
commit
8bb23bbcd9

+ 2 - 2
ems/ems-cloud/ems-server/src/main/resources/application-prod-ct.yml

@@ -33,13 +33,13 @@ spring:
         # 主库数据源
         master:
           driver-class-name: com.mysql.cj.jdbc.Driver
-          url: jdbc:mysql://10.0.8.20:3306/ems_ct?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+          url: jdbc:mysql://10.0.8.20:3306/ems_ct?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&connectTimeout=3000&socketTimeout=30000
           username: ems_ct
           password: Cxndix7rd2EdtrAd
         # 从库数据源
         slave:
           driver-class-name: com.mysql.cj.jdbc.Driver
-          url: jdbc:mysql://10.0.8.21:3306/ems_ct?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+          url: jdbc:mysql://10.0.8.21:3306/ems_ct?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&connectTimeout=3000&socketTimeout=30000
           username: ems_ct
           password: Cxndix7rd2EdtrAd
 

+ 5 - 1
ems/ems-core/src/main/java/com/ruoyi/ems/service/impl/ElecMeterHServiceImpl.java

@@ -5,6 +5,7 @@ import com.ruoyi.ems.domain.EnergyMeter;
 import com.ruoyi.ems.mapper.ElecMeterHMapper;
 import com.ruoyi.ems.model.QueryMeter;
 import com.ruoyi.ems.service.IElecMeterHService;
+import com.ruoyi.ems.util.DateRangeUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -76,8 +77,11 @@ public class ElecMeterHServiceImpl implements IElecMeterHService {
 
     @Override
     public EnergyMeter qryElecMeterByDate(String date, String areaCode) {
+        // 日期前缀转左闭右开区间,避免日期列 LIKE 前缀匹配导致索引失效
+        String[] range = DateRangeUtils.toHalfOpenRange(date);
         return elecMeterHMapper.qryElecMeterByDate(new ElecMeterH() {{
-            setStartRecTime(date);
+            setStartRecTime(null == range ? null : range[0]);
+            setEndRecTime(null == range ? null : range[1]);
             setAreaCode(areaCode);
         }});
     }

+ 7 - 0
ems/ems-core/src/main/java/com/ruoyi/ems/service/impl/ElecStoreServiceImpl.java

@@ -6,6 +6,7 @@ import com.ruoyi.ems.model.ElecStoreAnalyze;
 import com.ruoyi.ems.model.ElecStoreSta;
 import com.ruoyi.ems.model.QueryMeter;
 import com.ruoyi.ems.service.IElecStoreService;
+import com.ruoyi.ems.util.DateRangeUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -63,6 +64,12 @@ public class ElecStoreServiceImpl implements IElecStoreService {
 
     @Override
     public ElecStoreH selectStoreHByDataRange(ElecStoreH elecStoreH) {
+        // 日期前缀转左闭右开区间,避免日期列 LIKE 前缀匹配导致索引失效
+        String[] range = DateRangeUtils.toHalfOpenRange(elecStoreH.getStartRecTime());
+        if (null != range) {
+            elecStoreH.setStartRecTime(range[0]);
+            elecStoreH.setEndRecTime(range[1]);
+        }
         return elecStoreHMapper.selectStoreHByDataRange(elecStoreH);
     }
 

+ 5 - 1
ems/ems-core/src/main/java/com/ruoyi/ems/service/impl/WaterMeterHServiceImpl.java

@@ -6,6 +6,7 @@ import com.ruoyi.ems.domain.WaterMeterH;
 import com.ruoyi.ems.mapper.WaterMeterHMapper;
 import com.ruoyi.ems.model.QueryMeter;
 import com.ruoyi.ems.service.IWaterMeterHService;
+import com.ruoyi.ems.util.DateRangeUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -68,8 +69,11 @@ public class WaterMeterHServiceImpl implements IWaterMeterHService {
 
     @Override
     public EnergyMeter qryWaterMeterByDate(String dataRange, String areaCode) {
+        // 日期前缀转左闭右开区间,避免日期列 LIKE 前缀匹配导致索引失效
+        String[] range = DateRangeUtils.toHalfOpenRange(dataRange);
         return waterMeterHMapper.qryWaterMeterByDate(new WaterMeterH(){{
-            setStartRecTime(dataRange);
+            setStartRecTime(null == range ? null : range[0]);
+            setEndRecTime(null == range ? null : range[1]);
             setAreaCode(areaCode);
         }});
     }

+ 49 - 0
ems/ems-core/src/main/java/com/ruoyi/ems/util/DateRangeUtils.java

@@ -0,0 +1,49 @@
+package com.ruoyi.ems.util;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * 日期前缀工具:将年/月/日前缀转换为左闭右开日期区间,替代日期列上的 LIKE 前缀匹配(LIKE 会导致索引失效)
+ *
+ * @author ruoyi
+ */
+public class DateRangeUtils {
+    private static final DateTimeFormatter DATE_FORM = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+    /**
+     * 将日期前缀转换为左闭右开区间 [start, end)
+     *
+     * @param datePrefix 日期前缀,支持 yyyy、yyyy-MM、yyyy-MM-dd
+     * @return 长度为 2 的数组:[0]=起始日期(含)、[1]=结束日期(不含);格式不支持时返回 null
+     */
+    public static String[] toHalfOpenRange(String datePrefix) {
+        if (datePrefix == null || datePrefix.trim().isEmpty()) {
+            return null;
+        }
+        String p = datePrefix.trim();
+        try {
+            LocalDate start;
+            LocalDate end;
+            if (p.length() >= 10) {
+                start = LocalDate.parse(p.substring(0, 10), DATE_FORM);
+                end = start.plusDays(1);
+            }
+            else if (p.length() >= 7) {
+                start = LocalDate.parse(p.substring(0, 7) + "-01", DATE_FORM);
+                end = start.plusMonths(1);
+            }
+            else if (p.length() >= 4) {
+                start = LocalDate.parse(p.substring(0, 4) + "-01-01", DATE_FORM);
+                end = start.plusYears(1);
+            }
+            else {
+                return null;
+            }
+            return new String[] { start.format(DATE_FORM), end.format(DATE_FORM) };
+        }
+        catch (Exception e) {
+            return null;
+        }
+    }
+}

+ 1 - 1
ems/ems-core/src/main/resources/mapper/ems/ElecMeterHMapper.xml

@@ -179,7 +179,7 @@
         SELECT sum(elec_quantity) elec_quantity,
         SUM(use_elec_cost) use_elec_cost
         from adm_elec_meter_h aemh
-        where `date` like concat(#{startRecTime}, '%')
+        where `date` >= #{startRecTime} and `date` < #{endRecTime}
         <if test="areaCode != null and areaCode != '' and areaCode !='-1'">and aemh.area_code = #{areaCode}</if>
     </select>
 

+ 1 - 1
ems/ems-core/src/main/resources/mapper/ems/EmsEcoDMapper.xml

@@ -95,7 +95,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         COALESCE(CAST(water_eco_cost AS DECIMAL(10, 2)), 0)) water_eco_cost
         from adm_ems_eco_d d
         <where>
-            <if test="date != null and date != ''">DATE like concat(#{date}, '%')</if>
+            <if test="date != null and date != ''">`date` = #{date}</if>
             <if test="areaCode != null and areaCode != '' and areaCode != '-1'">
                 and area_code = #{areaCode}
             </if>

+ 1 - 1
ems/ems-core/src/main/resources/mapper/ems/EmsElecStoreHMapper.xml

@@ -67,7 +67,7 @@
         FROM adm_ems_elec_store_h st
         <where>
             <if test="areaCode != null  and areaCode != ''  and areaCode != '-1'">and st.area_code = #{areaCode}</if>
-            <if test="startRecTime != null and startRecTime !='' ">and st.`date` like concat(#{startRecTime},'%')</if>
+            <if test="startRecTime != null and startRecTime !='' ">and st.`date` &gt;= #{startRecTime} and st.`date` &lt; #{endRecTime}</if>
         </where>
     </select>
 

+ 1 - 1
ems/ems-core/src/main/resources/mapper/ems/WaterMeterHMapper.xml

@@ -129,7 +129,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         SELECT sum(water_quantity) water_quantity,
                SUM(use_water_cost) use_water_cost
         from adm_water_meter_h aemh
-        where `date` like concat(#{startRecTime}, '%')
+        where `date` &gt;= #{startRecTime} and `date` &lt; #{endRecTime}
         <if test="areaCode != null and areaCode != ''">and aemh.area_code = #{areaCode}</if>
     </select>
 

+ 4 - 2
ems/sql/ems_server.sql

@@ -1707,7 +1707,8 @@ create table adm_elec_meter_h (
   primary key (`id`),
   unique key ux_elec_meter_h(`device_code`, `record_time`),
   key idx_elec_meter_h_area_dev_date(`area_code`, `device_code`, `date`),
-  key idx_elec_meter_h_date(`date`)
+  key idx_elec_meter_h_date(`date`),
+  key idx_elec_meter_h_area_date(`area_code`, `date`)
 ) engine=innodb auto_increment=1 comment = '用电计量表-小时';
 
 
@@ -1731,7 +1732,8 @@ create table adm_water_meter_h (
   primary key (`id`),
   unique key ux_water_meter_h(`device_code`, `record_time`),
   key idx_water_meter_h_area_dev_date(`area_code`, `device_code`, `date`),
-  key idx_water_meter_h_date(`date`)
+  key idx_water_meter_h_date(`date`),
+  key idx_water_meter_h_area_date(`area_code`, `date`)
 ) engine=innodb auto_increment=1 comment = '用水计量表-小时';