SQL优化典型案例分析.doc
关键字:充分利用过滤条件
原始sql查询
SELECTDISTINCTASrowid,
ASid,
a.cstguid,
b.cstname,
Isnull(b.cardid,)AScardid,
Isnull(b.mobiletel,)++Isnull(b.hometel,)++Isnull(b.officetel,)ASlxtel,
ASoppguid,
a.buguid,
ASprojguid,
c.memlevel,
c.memcode,
c.memguid,
c.buguidAShjbuguid,
ASusername,
ASuserguid,
d.bunameAShjbuname
FROMp_cstattacha
LEFTJOINp_customerbONa.cstguid=b.cstguid
LEFTJOINh_membercONb.cstguid=c.cstguidANDc.memstatus=正式会员
LEFTJOINmybusinessunitdONc.buguid=d.buguid
WHERE(1=1)
AND(Isnull(b.mobiletel,)++Isnull(b.hometel,)++Isnull(b.officetel,)LIKE)
优化前的IO
表Worktable。扫描计数0,逻辑读取0次,物理读取0次,预读0次,lob逻辑读取0次,lob物理读取0次,lob预读0次。
表h_Member。扫描计数1,逻辑读取4818次,物理读取0次,预读0次,lob逻辑读取0次,lob物理读取0次,lob预读0次。
表p_CstAttach。扫描计数1,逻辑读取12897次,物理读取0次,预读0次,lob逻辑读取0次,lob物理读取0次,lob预读0次。
表p_Customer。扫描计数1,逻辑读取27222次,物理读取0次,预读0次,lob逻辑读取0次,lob物理读取0次,lob预读0次。
表myBusinessUnit。扫描计数1,逻辑读取6次,物理读取0次,预读0次,lob逻辑读取0次,lob物理读取0次,lob预读0次。
优化前的执行方案〔总估计子树本钱:56.239〕
优化过程分析
第一步:从业务角度分析。这里要找号码是的客户,拥有该号码的客户不会很多,为什么会有这么高的IO呢?很可能没有利用到索引,扫描产生这么大的IO;
第二步:看一下执行方案。确实是索引扫描。那么,有过滤条件为什么没有利用到索引呢?
第三步:分析一下sql。过滤条件不符合sARG标准:1、过滤条件左侧有函数;2、like条件左侧有百分号(%);怎么办?
第四步:再分析业务。操作员什么情况下会对号码做模糊查询?可能是这种情况:异地录入时前面加了0。买房人有多少使用异地呢?我统计了一下wk2008_5_13日的数据库,异地只占0.65%。为了满足0.65%的查询准确性牺牲99.35%查询性能有些不值得?;
第五步:我们能否这样改造呢?在普通查询中提供号码的精确查询,满足99.35%查询要求,在高级查询中使用模糊查询,满足另外0.65%的查询。
改造后的sql查询
SELECTDISTINCTASrowid,
ASid,
a.cstguid,
b.cstname,
Isnull(b.cardid,)AScardid,
Isnull(b.mobiletel,)++Isnull(b.hometel,)++Isnull(b.officetel,)ASlxtel,
ASo