SQL是Structured QueryLanguage的全称,指结构化面向对象。
SQL在网路上有许多的强化方法论,但在前述组织工作中能采用那些规范化强化方法论的情景极少。
日前,接到一封信网络管理电子邮件警示,辨认出SQL费时极短且继续执行单次非常多,对SQL展开强化就变得很有必要性。
一、SQL强化前情形
1、具体内容SQL句子如下表所示:
SELECT COUNT(DISTINCT A.ID_NO) FROM TM_APP_MAIN M,TM_APP_PRIM_APPLICANT_INFO A, TM_APP_PRIM_CONTACT_INFO C
WHERE 1=1 AND M.APP_NO=C.APP_NO(+) ANDM.APP_NO=A.APP_NO AND C.TEL_SOURCE=APPLY
AND C.DELETE_FLAG=0 ANDA.ID_NO<>510215********0016 AND M.STATUS NOT IN (J, C) AND(A.CELLPHONE = 138******74 OR C.CONTACT_MOBILE =138******74 ) ANDA.CREATE_TIME >= to_date(2016-01-01,yyyy-mm-dd)
2、从现实情形来看,每条SQL句子继续执行时间长达55秒左右。
3、继续执行计划如下表所示:
1 SIMPLE A ALL ID_NO,CREATE_TIME,APP_NO,ID_NO_2,CELLPHONE 1452930 Using where
1 SIMPLE M ref APP_NO,APP_NO_2,APP_NO_3,STATUSAPP_NO 63 buzi_data_tm.A.APP_NO 1 Usingwhere
1 SIMPLE C ref APP_NO,CONTACT_MOBILE,CONTACT_MOBILE_2 APP_NO 63 buzi_data_tm.A.APP_NO 2 Usingwhere
4、业务分析:该SQL查询为当前申请客户的联系人电话在最近6个月内在其他客户的联系人上出现的单次 (一个身份证计数为1)。
二、SQL强化过程
上面SQL没有太大的问题 ,但辨认出以下地方可作进一步强化:
一是从继续执行计划看,TM_APP_MAIN 主表都是全表扫描,每次都要查询140万的记录。
二是根据身份证号查询采用了 <> ,即使有索引也不会继续执行。
三是根据手机号查询条件中采用了 OR,即使有索引也不会继续执行,从上面的继续执行计划能看到,且辅助表的数据远远超过140万的记录再做全表扫描就非常效率低下了。
对以上几个地方,特别是不能采用查询的地方展开了强化。
根据一般SQL查询的强化方案,对于OR一般采用UNION来代替,这样对于手机号码的查询就能用到很好的索引,修改后查询SQL如下表所示:
SELECT
COUNT(DISTINCTA.ID_NO)
FROM
(
SELECT
APP_NO
FROM
TM_APP_MAIN
WHERE
STATUSNOT IN (J, C)
)M left join
(
SELECT
APP_NO,
ID_NO
FROM
TM_APP_PRIM_APPLICANT_INFO
WHERE
CREATE_TIME>= to_date(2016-01-01,yyyy-mm-dd)
ANDcellphone = 138******74
ANDid_no <> 510215********0016
UNIONALL
SELECT
app_no,
ID_NO
FROM
TM_APP_PRIM_CONTACT_INFO
WHERE
contact_mobIle= 138******74
ANDTEL_SOURCE = APPLY
ANDDELETE_FLAG = 0
ANDNOT EXISTS (
SELECT
1
FROM
TM_APP_PRIM_APPLICANT_INFO
WHERE
TM_APP_PRIM_APPLICANT_INFO.app_no= TM_APP_PRIM_CONTACT_INFO.app_no
ANDTM_APP_PRIM_APPLICANT_INFO.id_no = 510215********0016
)
)A
on M.APP_NO = A.APP_NO;
继续执行计划如下表所示:MYSQL版本
1 PRIMARY ALL 4 Using where
1 PRIMARY ref 63 A.APP_NO 13884 Usingindex
3 DERIVEDdws_dsst_rmps_TM_APP_PRIM_APPLICANT_INFO ref ID_NO,CREATE_TIME,ID_NO_2,CELLPHONE CELLPHONE 63 const 1 Usingindex condition; Using where
4 UNION dws_dsst_rmps_TM_APP_PRIM_CONTACT_INFO ref CONTACT_MOBILE,CONTACT_MOBILE_2 CONTACT_MOBILE63 const 1 Usingindex condition; Using where
5 DEPENDENTSUBQUERYdws_dsst_rmps_TM_APP_PRIM_APPLICANT_INFO ref ID_NO,APP_NO,ID_NO_2 ID_NO 93 const 1 Using index condition; Using where
UNIONRESULT ALL Usingtemporary
2 DERIVEDdws_dsst_rmps_TM_APP_MAIN ALL STATUS 1452930 Using where
三、结语
SQL强化以后,从MYSQL继续执行情形来看,对于两个辅助的大表,都能正常的采用手机号作为查询条件,并且继续执行时间由55秒下降为0.3秒,一个非常小的强化规范化就带来如此巨大的强化效果,真可谓于细微处见真章!