1. 程式人生 > >一些關於SQL優化的總結

一些關於SQL優化的總結

roc nco pla city sel 執行 crt _id emp

慢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優化的總結