系統優化期間,須要找到優化後最能帶來效益的點進行優化,這樣才能從根本上提高系統運行效率。sql
如下內容以某個保單增量處理程序邏輯進行分析。當前增量保單事實提取過程分爲如下兩步:
a. 經過upd_time增量查詢出各個關聯表的增量cntr_id主鍵並插入tmp_f_cntr_v8_cntrrange臨時表;
b. 經過tmp_f_cntr_v8_cntrrange表與std_contract等表JOIN操做,獲取增量保單數據。
1. 增量範圍肯定
1.1 業務行爲共用增量控制表:
當前現狀描述:互不交叉的業務行爲(例如新契約個單、合同團單、新契約團單等)共用同一張tmp_f_cntr_v8_cntrrange增量控制表,以下:
問題:
不一樣業務行爲共用tmp_f_cntr_v8_cntrrange增量表,同時都採用tmp_f_cntr_v8_cntrrange表提取增量數據,無故成倍地增長了增量數據範圍。
解決方案:
應該爲各業務行爲建立單獨的增量表(例如tmp_f_cntr_v8_cntrrange_appl_psn、tmp_f_cntr_v8_cntrrange_appl_grp、tmp_f_cntr_v8_cntrrange_cntr_grp等),並經過這些增量表提取保單數據。
1.2 upd_time肯定增量保單範圍:
當前現狀描述:
代碼以下:app
- select cntr_idas CNTR_NO,'999'as POL_CODE,'2'as APP_STD_FLAG from std_contract where upd_time>=?and upd_time<?
- union
- select distinctcntr_id as CNTR_NO,'999'as POL_CODE,'2'as APP_STD_FLAG from cntr_basic_state whereupd_time>=?and upd_time<?
- union
- select distinctcntr_id as CNTR_NO,'999'as POL_CODE,'2'as APP_STD_FLAG from cntr_sub_state where upd_time>=?and upd_time<?
- union
- select distinctcntr_id as CNTR_NO,'999'as POL_CODE,'2'as APP_STD_FLAG from insured whereupd_time>=? and upd_time<?
- union
- select distinctcntr_id as CNTR_NO,'999'as POL_CODE,'2'as APP_STD_FLAG from psn_cntr_holder whereupd_time>=?and upd_time<?
- union
- select distinctcntr_id as CNTR_NO,'999'as POL_CODE,'2'as APP_STD_FLAG from if_of_alt whereupd_time>=? and upd_time<?
- union
- select distinctstd_contract.cntr_idas CNTR_NO,'999'as POL_CODE,'2'as APP_STD_FLAG from grant_tranlst,std_contractwhere std_contract.cntr_no=grant_tranlst.cntr_noand grant_tranlst.upd_time>=?and grant_tranlst.upd_time<?
- union
- select distinctcntr_id as CNTR_NO,'999'as POL_CODE,'2'as APP_STD_FLAG from insur_appl_cv_task,std_contractwhere insur_appl_cv_task.rel_key_no=std_contract.appl_noand insur_appl_cv_task.upd_time>=?and insur_appl_cv_task.upd_time<?
問題:
目前在相關表上的upd_time字段(也只此字段)均加了索引,可是要得到cntr_id時,仍然須要經過lookup rid到原始表中取出cntr_id字段(索引葉子節點沒有cntr_id)。這裏存在三點問題:
1). lookup rid以獲得cntr_id的操做,是upd_time索引查找範圍語句資源消耗的大頭,lookup rid只適合於小數據量;
2). lookup rid查找原表(由於有不少其餘任務訪問原表)會增長系統阻塞的機率及下降I/O量;
3). 可能會由於返回數據量大,使得upd_time索引失效。
優化方法:
每張表修改upd_time索引,經過在索引中包含相關字段(例如cntr_id),消除lookup rid操做,將整個增量查找過程轉換爲索引查找,能夠完全解決以上三個問題
2. 保單增量事實獲取:
當前現狀描述:
獲取保單增量事實的代碼可參見後文《優化前.sql》。
問題:
全部的相關表都是全表(這些表都是大表。固然,語句中有where語句,但仍然是從全表中過濾數據)JOIN,並經過tmp_f_cntr_v8_cntrrange增量範圍表提取出增量數據。這裏面存在如下問題:
1). 全部表(例如std_contract、cntr_sub_state等)均經過where語句,以及與tmp_f_cntr_v8_cntrrange表關聯獲得增量數據。這依賴於where語句中的索引,以及和tmp_f_cntr_v8_cntrrange表的關聯索引狀況,不然極可能引發全表掃描(這種狀況很是可怕);
2). 在上文1.2肯定增量範圍時,upd_time索引以及lookup rid已經獲得了各個表的增量數據,獲取保單事實的時候對同一張表又作了一次重複的訪問,沒有必要;
3). 通過分析,對絕大部分表(都是大表)使用的字段都很是的少,進行全表操做很是的不划算。
解決方案:
整合「肯定保單增量範圍」、「提取保單事實」兩個步驟:
絕大部分表的「保單事實使用到的字段」上建立索引(若是包含upd_time,可同時解決增量範圍的問題),能夠將表掃描轉換爲索引掃描(字段少因此索引會很小),徹底能夠下降系統阻塞(由於只須要訪問索引,不須要和其它任務爭搶原表),下降I/O量;優化
優化前:spa
- SELECT e.PROV_BRANCH_CODE AS PROV_BRANCH_CODE,
- a.appl_no AS APPL_NO,
- a.cntr_no AS CNTR_NO,
- CASE
- WHEN a.mr_type = 'M' THEN a.cntr_no
- ELSE (SELECT TOP 1 cntr_no
- FROM std_contractwith(nolock)
- WHERE a.master_cntr_id = std_contract.cntr_id
- AND std_contract.incr_flag <> '2')
- END ASMASTER_CNTR_NO,
- a.sg_no ASSG_NO,
- Ltrim(Rtrim(CONVERT(VARCHAR(6), a.mgr_branch_no))) AS TOWN_BRANCH_CODE,
- dbo.Pub_salesno(a.n_sales_branch_no, a.n_sales_code, 8)AS KEY_SALER_ID,
- Isnull(a.n_sales_branch_no, '!') ASBRANCH_NO,
- Isnull(a.n_sales_code, '!') AS AGENT_NO,
- a.sales_channel AS SALES_CHANNEL_CODE,
- '!' ASMANAGE_CHANNEL_CODE,
- '!' ASCENTER_CODE,
- a.pol_code ASPOL_CODE,
- CASE
- WHEN a.moneyin_itrvl = 'W' THEN 1
- ELSE b.moneyin_dur
- END ASMONEY_DUR,
- a.moneyin_itrvl AS ITRVL_CODE,
- d.ipsn_cust_no AS KEY_IPSN_CUST_ID,
- (SELECT TOP1 hldr_cust_no
- FROM psn_cntr_holderwith(nolock)
- WHERE a.cntr_id = psn_cntr_holder.cntr_id
- AND psn_cntr_holder.incr_flag <> '2'
- ORDER BY psn_cntr_holder.upd_timeDESC) ASKEY_HLDR_CUST_ID,
- CASE
- WHEN b.insur_dur_unit = 'W' THEN 999
- ELSE b.insur_dur
- END ASINSUR_DUR,
- a.in_force_date AS IN_FORCE_DATE,
- a.sign_date AS SIGN_DATE,
- a.cntr_term_date AS TERM_DATE,
- CASE
- WHEN a.cg_no IS NULL THEN (SELECT TOP 1 Cast(ext_key12 AS DATETIME)
- FROM insur_appl_cv_task h WITH(nolock)
- WHERE a.appl_no = h.rel_key_no
- AND a.cntr_no = h.ext_key9
- AND Isdate(h.ext_key12) = 1
- AND h.incr_flag <> '2'
- ORDER BY task_seq DESC)
- ELSE (SELECT TOP 1 Cast(ext_key12 AS DATETIME)
- FROM insur_appl_cv_taskh WITH(nolock)
- WHERE a.appl_no = h.rel_key_no
- AND a.cg_no = h.ext_key9
- AND Isdate(h.ext_key12) = 1
- AND h.incr_flag <> '2'
- ORDER BY task_seq DESC)
- END ASRESP_DATE,
- a.mr_type AS MR_TYPE_CODE,
- a.cntr_stat AS CNTR_STAT,
- a.cntr_type AS CNTR_TYPE_CODE,
- 8 ASDATA_SRC_ID,
- z.std_premium AS FACT_STD_PREM,
- z.face_amnt AS FACT_FACE_AMNT,
- d.ipsn_num AS FACT_IPSN_NUM,
- a.cntr_term_cause AS CNTR_STOP_CODE,
- z.stop_moneyin_date AS STOP_MONEYIN_DATE,
- a.cntr_expiry_date AS EXPIRY_DATE,
- f.out_force_date AS OUT_FORCE_DATE,
- f.re_in_force_date AS RE_IN_FORCE_DATE,
- Substring(a.appl_no, 1, 4) AS CARD_CODE,
- CASE
- WHEN a.Sales_channelin('OA', 'SP') THEN dbo.Pub_salesno(a.n_sales_branch_no, a.n_sales_code, 8)
- ELSE '-1'
- END ASKEY_SITE_ID,
- Dateadd(day, -1, auto_in_force_date) ASENROLL_DATE,
- (SELECT TOP1 contact_seq
- FROM psn_cntr_holderwith(nolock)
- WHERE a.cntr_id = psn_cntr_holder.cntr_id
- AND psn_cntr_holder.incr_flag <> '2'
- ORDER BY psn_cntr_holder.upd_timeDESC) ASCONTACT_SEQ,
- CASE
- WHEN g.cntr_no IS NOT NULL THEN 1
- ELSE 0
- END ASBANK_FLAG,
- a.renew_flag AS RENEW_FLAG,
- a.renew_times AS RENEW_TIMES,
- '!' ASKEY_MERG_CUST_ID,
- 1 ASAPPL_STD_FLAG,
- a.incr_flag AS INCR_FLAG,
- a.cntr_id AS EXT_KEY,
- a.moneyin_type ASMONEYIN_TYPE,
- a.bank_code AS BANK_CODE,
- a.bank_acc_no AS BANK_ACC_NO,
- a.acc_cust_name AS ACC_CUST_NAME,
- a.appl_date AS APPL_DATE,
- a.lose_reg_num AS LOSE_NUM
- FROM tmp_f_cntr_v8_cntrrangeewith(nolock)
- INNER JOIN std_contract a WITH(nolock)
- ON a.cntr_id = e.cntr_no
- LEFT JOIN cntr_basic_statebwith(nolock)
- ON a.cntr_id = b.cntr_id
- AND b.incr_flag <> '2'
- LEFT JOIN(SELECT cntr_id,
- Min(ipsn_cust_no)AS ipsn_cust_no,
- Count(cntr_id) AS ipsn_num,
- e.PROV_BRANCH_CODE,
- e.BATCH_NO
- FROM tmp_f_cntr_v8_cntrrangee WITH(nolock)
- INNER JOIN insured WITH(nolock)
- ON cntr_id = e.cntr_no
- WHERE incr_flag <> '2'
- AND e.APP_STD_FLAG = '2'
- AND ipsn_cust_no IS NOT NULL
- GROUP BY cntr_id,
- e.PROV_BRANCH_CODE,
- e.BATCH_NO)AS d
- ON a.cntr_id = d.cntr_id
- AND d.BATCH_NO = e.BATCH_NO
- AND d.PROV_BRANCH_CODE = e.PROV_BRANCH_CODE
- LEFT JOIN(SELECT cntr_id,
- Sum(std_premium) AS std_premium,
- Sum(face_amnt) AS face_amnt,
- Max(stop_moneyin_date)AS stop_moneyin_date,
- e.PROV_BRANCH_CODE,
- e.BATCH_NO
- FROM tmp_f_cntr_v8_cntrrangee WITH(nolock)
- INNER JOIN cntr_sub_state WITH(nolock)
- ON cntr_id = e.cntr_no
- WHERE incr_flag <> '2'
- AND e.APP_STD_FLAG = '2'
- GROUP BY cntr_id,
- e.PROV_BRANCH_CODE,
- e.BATCH_NO)AS z
- ON a.cntr_id = z.cntr_id
- AND z.BATCH_NO = e.BATCH_NO
- AND z.PROV_BRANCH_CODE = e.PROV_BRANCH_CODE
- LEFT JOIN(SELECT cntr_id,
- Max(out_force_date) AS out_force_date,
- Max(re_in_force_date)AS re_in_force_date,
- e.PROV_BRANCH_CODE,
- e.BATCH_NO
- FROM tmp_f_cntr_v8_cntrrangee WITH(nolock)
- INNER JOIN if_of_alt WITH(nolock)
- ON cntr_id = e.cntr_no
- WHERE incr_flag <> '2'
- AND e.APP_STD_FLAG = '2'
- GROUP BY cntr_id,
- e.PROV_BRANCH_CODE,
- e.BATCH_NO)AS f
- ON a.cntr_id = f.cntr_id
- AND f.BATCH_NO = e.BATCH_NO
- AND f.PROV_BRANCH_CODE = e.PROV_BRANCH_CODE
- LEFT JOIN(SELECT DISTINCT grant_tranlst.cntr_no,
- e.PROV_BRANCH_CODE,
- e.BATCH_NO
- FROM tmp_f_cntr_v8_cntrrangee WITH(nolock)
- INNER JOIN grant_tranlst WITH(nolock)
- ON grant_tranlst.cntr_no = e.cntr_no
- WHERE incr_flag <> '2'
- AND e.APP_STD_FLAG = '2')AS g
- ON a.cntr_no = g.cntr_no
- AND g.BATCH_NO = e.BATCH_NO
- AND g.PROV_BRANCH_CODE = e.PROV_BRANCH_CODE
- WHERE a.cntr_no IS NOT NULL
- AND a.cntr_type <> 'M'
- AND a.pol_code <> '263'
- AND e.APP_STD_FLAG = '2'
- AND Isnumeric(a.renew_flag) = 1
- AND e.PROV_BRANCH_CODE = ?
- AND e.BATCH_NO = ?
優化後:code
- SELECT a.appl_no AS APPL_NO,
- a.cntr_no AS CNTR_NO,
- CASE
- WHEN a.mr_type = 'M' THEN a.cntr_no
- ELSE (SELECT TOP 1 cntr_no
- FROM std_contract WITH(nolock)
- WHERE a.master_cntr_id = std_contract.cntr_id)
- END ASMASTER_CNTR_NO,
- a.sg_no ASSG_NO,
- Ltrim(Rtrim(CONVERT(VARCHAR(6), a.mgr_branch_no))) AS TOWN_BRANCH_CODE,
- dbo.Pub_salesno(a.n_sales_branch_no, a.n_sales_code, 8)AS KEY_SALER_ID,
- Isnull(a.n_sales_branch_no, '!') AS BRANCH_NO,
- Isnull(a.n_sales_code, '!') AS AGENT_NO,
- a.sales_channel AS SALES_CHANNEL_CODE,
- '!' ASMANAGE_CHANNEL_CODE,
- '!' ASCENTER_CODE,
- a.pol_code AS POL_CODE,
- CASE
- WHEN a.moneyin_itrvl = 'W' THEN 1
- ELSE b.moneyin_dur
- END ASMONEY_DUR,
- a.moneyin_itrvl AS ITRVL_CODE,
- d.ipsn_cust_no AS KEY_IPSN_CUST_ID,
- (SELECT TOP1 hldr_cust_no
- FROM psn_cntr_holderWITH(nolock)
- WHERE a.cntr_id = psn_cntr_holder.cntr_id
- AND psn_cntr_holder.incr_flag <> '2'
- ORDER BY psn_cntr_holder.upd_time DESC) ASKEY_HLDR_CUST_ID,
- CASE
- WHEN b.insur_dur_unit = 'W' THEN 999
- ELSE b.insur_dur
- END ASINSUR_DUR,
- a.in_force_date AS IN_FORCE_DATE,
- a.sign_date ASSIGN_DATE,
- a.cntr_term_date AS TERM_DATE,
- CASE
- WHEN a.cg_no IS NULL THEN (SELECT TOP 1 Cast(ext_key12 AS DATETIME)
- FROM insur_appl_cv_task hWITH(nolock)
- WHERE a.appl_no = h.rel_key_no
- AND a.cntr_no = h.ext_key9
- AND Isdate(h.ext_key12) = 1
- AND h.incr_flag <> '2'
- ORDER BY task_seq DESC)
- ELSE (SELECT TOP 1 Cast(ext_key12 AS DATETIME)
- FROM insur_appl_cv_taskh WITH(nolock)
- WHERE a.appl_no = h.rel_key_no
- AND a.cg_no = h.ext_key9
- AND Isdate(h.ext_key12) = 1
- AND h.incr_flag <> '2'
- ORDER BY task_seq DESC)
- END ASRESP_DATE,
- a.mr_type AS MR_TYPE_CODE,
- a.cntr_stat AS CNTR_STAT,
- a.cntr_type ASCNTR_TYPE_CODE,
- 8 ASDATA_SRC_ID,
- z.std_premium AS FACT_STD_PREM,
- z.face_amnt ASFACT_FACE_AMNT,
- d.ipsn_num AS FACT_IPSN_NUM,
- a.cntr_term_cause AS CNTR_STOP_CODE,
- z.stop_moneyin_date AS STOP_MONEYIN_DATE,
- a.cntr_expiry_date AS EXPIRY_DATE,
- f.out_force_date AS OUT_FORCE_DATE,
- f.re_in_force_date ASRE_IN_FORCE_DATE,
- Substring(a.appl_no, 1, 4) AS CARD_CODE,
- CASE
- WHEN a.Sales_channelin('OA', 'SP') THEN dbo.Pub_salesno(a.n_sales_branch_no, a.n_sales_code, 8)
- ELSE '-1'
- END ASKEY_SITE_ID,
- Dateadd(day, -1, auto_in_force_date) ASENROLL_DATE,
- (SELECT TOP1 contact_seq
- FROM psn_cntr_holderWITH(nolock)
- WHERE a.cntr_id = psn_cntr_holder.cntr_id
- AND psn_cntr_holder.incr_flag <> '2'
- ORDER BY psn_cntr_holder.upd_timeDESC) ASCONTACT_SEQ,
- CASE
- WHEN g.cntr_no IS NOT NULL THEN 1
- ELSE 0
- END ASBANK_FLAG,
- a.renew_flag AS RENEW_FLAG,
- a.renew_times AS RENEW_TIMES,
- '!' ASKEY_MERG_CUST_ID,
- 1 ASAPPL_STD_FLAG,
- a.incr_flag AS INCR_FLAG,
- a.cntr_id AS EXT_KEY,
- a.moneyin_type AS MONEYIN_TYPE,
- a.bank_code AS BANK_CODE,
- a.bank_acc_no ASBANK_ACC_NO,
- a.acc_cust_name AS ACC_CUST_NAME,
- a.appl_date AS APPL_DATE,
- a.lose_reg_num ASLOSE_NUM
- FROM csipdb.std_contract_tmpa WITH(nolock)
- LEFT JOIN csipdb.cntr_basic_state_tmpbWITH(nolock)
- ON a.cntr_id = b.cntr_id
- AND b.incr_flag <> '2'
- LEFT JOIN(SELECT cntr_id,
- Min(ipsn_cust_no)AS ipsn_cust_no,
- Count(cntr_id) AS ipsn_num
- FROM csipdb.insured_tmpWITH(nolock)
- WHERE incr_flag <> '2'
- AND ipsn_cust_no IS NOT NULL
- GROUP BY cntr_id)AS d
- ON a.cntr_id = d.cntr_id
- LEFT JOIN(SELECT cntr_id,
- Sum(std_premium) AS std_premium,
- Sum(face_amnt) AS face_amnt,
- Max(stop_moneyin_date)AS stop_moneyin_date
- FROM csipdb.cntr_sub_state_tmpWITH(nolock)
- WHERE incr_flag <> '2'
- GROUP BY cntr_id)AS z
- ON a.cntr_id = z.cntr_id
- LEFT JOIN(SELECT cntr_id,
- Max(out_force_date) AS out_force_date,
- Max(re_in_force_date)AS re_in_force_date
- FROM csipdb.if_of_alt_tmpWITH(nolock)
- WHERE incr_flag <> '2'
- GROUP BY cntr_id)AS f
- ON a.cntr_id = f.cntr_id
- LEFT JOIN(SELECT DISTINCT cntr_no
- FROM csipdb.grant_tranlst_tmp WITH(nolock)
- WHERE incr_flag <> '2')AS g
- ON a.cntr_no = g.cntr_no
- WHERE a.cntr_no IS NOT NULL
- AND a.cntr_type <> 'M'
- AND a.pol_code <> '263'
- AND Isnumeric(a.renew_flag) = 1