注册

like 条件使用变量绑定后执行变慢

道荣 2023/02/02 1445 6 已解决

为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:
select * from v$version
03134283950-20221121-175072-20024
DB Version: 0x7000c
DM Database Server 64 V8
【操作系统】:linux

【CPU】: x86
【问题描述】*:
一个简单的语句, 在达梦管理工具执行只要 0.1s,
但是在 java 的 mybatis 中 like 条件使用变量绑定后 需要1s.
经过测试怀疑是 like 条件使用 绑定变量后, 导致优化器无法给出最优的执行计划, 请问是否有办法在不改sql语句的情况下, 得到正确的执行计划?

  1. 普通 语句
SELECT COUNT(*) as cn 
FROM ibms_brm_eqm_eqd_basic a 
WHERE a.IS_DEL = '0'
 AND a.equlocarecod like '62%' 
 AND a.EQUCLACODE LIKE '1%'  ;

查询花费 0.1

执行计划

1   #NSET2: [18, 1, 144] 
2     #PRJT2: [18, 1, 144]; exp_num(1), is_atom(FALSE) 
3       #AAGR2: [18, 1, 144]; grp_num(0), sfun_num(1), distinct_flag[0]; slave_empty(0)
4         #SLCT2: [18, 13279, 144]; (A.IS_DEL = '0' AND A.EQULOCARECOD >= '62' AND A.EQULOCARECOD < '63')
5           #BLKUP2: [18, 15462, 144]; I#EQUCLACODE#STACHEORGUNICODE(A)
6             #SSEK2: [18, 15462, 144]; scan_type(ASC), I#EQUCLACODE#STACHEORGUNICODE(IBMS_BRM_EQM_EQD_BASIC as A), scan_range['1','2')
  1. mybatis 使用变量
SELECT COUNT(*) as cn 
FROM ibms_brm_eqm_eqd_basic a 
WHERE a.IS_DEL = '0'
 AND a.equlocarecod like #{equlocarecod}
 AND a.EQUCLACODE LIKE '1%'  ;

查询花费 1s, 慢了10倍,

  1. 在 达梦管理工具 使用 ? 号作为变量
SELECT COUNT(*) as cn 
FROM ibms_brm_eqm_eqd_basic a 
WHERE a.IS_DEL = '0'
 AND a.equlocarecod like ?
 AND a.EQUCLACODE LIKE '1%'  ;

查询花费 1s

执行计划

1   #NSET2: [13, 1, 144] 
2     #PRJT2: [13, 1, 144]; exp_num(1), is_atom(FALSE) 
3       #AAGR2: [13, 1, 144]; grp_num(0), sfun_num(1), distinct_flag[0]; slave_empty(0)
4         #SLCT2: [13, 24, 144]; (A.IS_DEL = '0' AND A.EQUCLACODE >= '1' AND A.EQUCLACODE < '2' AND A.EQULOCARECOD LIKE exp_param(no:0))
5           #BLKUP2: [13, 11153, 144]; IBMS_D_BASIC_EQULOCARECOD(A)
6             #SSEK2: [13, 11153, 144]; scan_type(ASC), IBMS_D_BASIC_EQULOCARECOD(IBMS_BRM_EQM_EQD_BASIC as A), scan_range[exp11,exp11)
  1. 使用 优化的条件
SELECT COUNT(*) as cn FROM ibms_brm_eqm_eqd_basic a 
WHERE a.IS_DEL = '0' AND a.equlocarecod >= ? 
and a.equlocarecod < ?  
AND a.EQUCLACODE LIKE '1%';

输入 62, 63

花费 0.1s

执行计划

1   #NSET2: [13, 1, 144] 
2     #PRJT2: [13, 1, 144]; exp_num(1), is_atom(FALSE) 
3       #AAGR2: [13, 1, 144]; grp_num(0), sfun_num(1), distinct_flag[0]; slave_empty(0)
4         #SLCT2: [13, 498, 144]; (A.IS_DEL = '0' AND A.EQUCLACODE >= '1' AND A.EQUCLACODE < '2')
5           #BLKUP2: [13, 11153, 144]; IBMS_D_BASIC_EQULOCARECOD(A)
6             #SSEK2: [13, 11153, 144]; scan_type(ASC), IBMS_D_BASIC_EQULOCARECOD(IBMS_BRM_EQM_EQD_BASIC as A), scan_range[exp_param(no:0),exp_param(no:1))
回答 0
暂无回答
扫一扫
联系客服