一些關於SQL優化的總結
慢SQL核查
NO.1 :com.cmos.dao.basesr.TSrProblemProcesExceptionMapper.queryExceptionCount
SELECT
count(1)
FROM
t_sr_problem_proces t1,
(
SELECT
WRKFM_ID
FROM
t_sr_problem_process_modify
GROUP BY
WRKFM_ID
) t2
WHERE
t1.ACPT_TIME >= ‘2018-07-31 00:00:00‘
AND t1.ACPT_TIME <= ‘2018-08-31 23:59:59‘
AND t1.TENANT_ID = ‘100000‘
AND t1.PROV_CODE = ‘00030016‘
AND t1.WRKFM_ID = t2.WRKFM_ID
AND t1.WRKFM_STS_CD IN (‘3‘, ‘4‘, ‘5‘, ‘7‘, ‘8‘);
分析:
子查詢的結果集t2在與t1表聯合時會走全表掃描,且沒有索引。
改造:
SELECT
count(distinct t1.WRKFM_ID)
FROM
t_sr_problem_proces t1,
t_sr_problem_process_modify t2
WHERE
t1.ACPT_TIME >= ‘2018-07-31 00:00:00‘
AND t1.ACPT_TIME <= ‘2018-08-31 23:59:59‘
AND t1.TENANT_ID = ‘100000‘
AND t1.PROV_CODE = ‘00030016‘
AND t1.WRKFM_ID = t2.WRKFM_ID
AND t1.WRKFM_STS_CD IN (‘3‘, ‘4‘, ‘5‘, ‘7‘, ‘8‘);
改造後的SQL兩條執行計劃均走索引查詢
NO.2 com.cmos.dao.basesr.TSrProblemProcesExceptionMapper.queryExceptionCount_His
SELECT
count(1)
FROM
t_sr_problem_proces_h_2018 t1,
(
SELECT
WRKFM_ID
FROM
t_sr_problem_process_modify_his_2018
GROUP BY
WRKFM_ID
) t2
WHERE
t1.ACPT_TIME >= ?
AND t1.ACPT_TIME <= ?
AND t1.TENANT_ID = ?
AND t1.PROV_CODE = ?
AND t1.WRKFM_ID = t2.WRKFM_ID
分析:
子查詢的結果集t2在與t1表聯合時會走全表掃描,且沒有索引。
NO.3 com.cmos.service.commonsv.generator.TSrCfgHotSrtypeMapper.selectByCond
SELECT
REC_ID,
TENANT_ID,
PROV_CODE,
SRV_REQST_TYPE_ID,
CITY_CODE,
SRV_REQST_BIG_CLA_ID,
HTPOINT_SRV_REQST_TYPE_NM,
HTPOINT_SRV_REQST_TYPE_FULL_NM,
OP_STAFF_ID,
ARGE_SEQNO,
ORG_BRNCH_ID,
CRT_TIME,
MODF_TIME,
HTPOINT_SRV_TYPE_CD,
BATCH_NUM,
VALID_FLAG,
ACPT_FLAG,
BIG_CLA_NM,
LTSZ_WRKFM_FLAG,
EFF_TIME,
INVLD_TIME,
FRONT_SHOW_NM
FROM
t_sr_cfg_hot_srtype
ORDER BY
?
LIMIT ?,?
分析:
手動熱點服務請求類型查詢:
1.該SQL是簡單的單標查詢,經過排查該xml中的sql語句可以刪除
distinct
2.該sql查詢的字段可以看出,包含主鍵,因此distinct 將毫無意義,如果誤傳的話還會降低該查詢的性能
該查詢是簡單的單表查詢,經核查 t_sr_cfg_hot_srtype 在配置庫,所有省份共用一張表,該表主鍵是REC_ID,在查詢是REC_ID不會由前臺傳過來,因此where 子句中不會有 REC_ID 導致查詢不會走索引查
改造: 建議對於該表新增其他列的索引
NO.4 com.cmos.service.commonsv.generator.TSrCfgHotSrtypeRuleMapper.selectByCond
SELECT
RULE_ID,
TENANT_ID,
PROV_CODE,
HTPOINT_SRV_TYPE_CD,
EMBR_CITY_FLAG,
EMBR_BIG_CLA_FLAG,
INTERVALG,
TOPN,
OP_STAFF_ID,
ORG_BRNCH_ID,
CRT_TIME,
MODF_TIME
FROM
t_sr_cfg_hot_srtype_rule
WHERE
?
ORDER BY
?
分析:
1.該SQL是簡單的單標查詢,經過排查該xml中的sql語句可以刪除distinct
該sql查詢的字段可以看出,包含主鍵,因此distinct 將毫無意義,如果誤傳的話還會降低該查詢的性能
2.該表位於配置庫,多省共用一張表存儲數據,經查詢該表僅有主鍵一個索引,在查詢時不會傳主鍵到where 子句中,因此導致該簡單查詢為全表掃描且不走索引,無論哪個省的數據量足夠大都會影響其他省的正常查詢。
改進:建議該表新增索引
NO.5 com.cmos.dao.basesr.TSrProcessDetailHisMapper.selectByRouteLgIds
SELECT
DSPS_PROC_ID,
TENANT_ID,
LG_ID,
ROUTE_LG_ID,
WRKFM_ID,
OP_TYPE_CD,
FCT_NO,
FCT_NM,
FCT_VAL,
DSPS_STAFF_ID,
DSPS_ORG_BRNCH_ID,
CRT_TIME,
MODF_TIME,
PROV_CODE,
ELEMENT_DISPLAY_NAME
FROM
t_sr_process_detail_his_201808
WHERE
ROUTE_LG_ID IN (?,?,?)
分析:
1.排查xml的時候,發現#{id} 沒有添加jdbcType
2.以 t_sr_process_detail_his_201808 為例,該表中除主鍵外 還有在WRKFM_ID上有索引,但是針對該SQL WRKFM_ID 不在where子句中,因此查詢為全表掃面且不走索引
改進:在 ROUTE_LG_ID 字段上添加索引
NO.6 SrPageInfo.selectCfgPageType
SELECT DISTINCT
(APP_CLFC_CD)
FROM
t_sr_page_info
WHERE
TENANT_ID = ?
AND PROV_CODE = ?
分析:
t_sr_page_info位於配置庫,主鍵:PAGE_ID 除主鍵外無其他索引
該查詢雖然是簡單查詢,但是在數據量很大的時候,全表掃面會效率極低。
改進:在PROV_CODE 字段上新增索引
查詢表中索引:
show index from table_name
一些關於SQL優化的總結