| ||
|
开始写的子查询语句实现如下:
select c.corp_cnname from t_buss_corporation c where c.corp_no in
(
select mainA.Corp_No from t_buss_main_account mainA where MainA.Main_Acnt_No in
(
select cAccount.Main_Acnt_No from t_Buss_Child_Account cAccount where cAccount.Child_Acnt_No in
(
select CA.CHILD_ACNT_NO from T_BUSS_CARD CA where CA.Memb_Card_No=9123456701
)
)
)
改写后的SQL: 使用关联查询如下:
select c.corp_cnname from
(
(T_BUSS_CARD CA inner join t_Buss_Child_Account childA on childA.Child_Acnt_No=CA.Child_Acnt_No)
inner join t_buss_main_account mainA on childA.Main_Acnt_No=mainA.Main_Acnt_No
) inner join t_buss_corporation c on c.corp_no=mainA.Corp_No
where CA.Memb_Card_No =9123456701
下面测试转自一位数据管理人员的测试结果:
SQL优化--使用关联查询代替子查询
测试例子:
子查询:
(select workflowname from workflowbase where id=workflowid) workflowname
from [[zping.com]]] a
where a.operator='402882ed1112669201112a8385892f33'
执行结果:
表 'Worktable'。扫描计数 360,逻辑读取 142334 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'workflowbase'。扫描计数 1,逻辑读取 1589 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 '[zping.com]'。扫描计数 1,逻辑读取 366 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
关联查询:
from [[zping.com]]] a inner join workflowbase b on a.workflowid=b.id
where operator='402882ed1112669201112a8385892f33'
执行结果:
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'workflowbase'。扫描计数 1,逻辑读取 1589 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 '[zping.com]'。扫描计数 1,逻辑读取 366 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
这里:子查询IO次数:142334 +1589+366=144289
关联查询IO次数:1589 +366 =1922
关联查询是子查询的75倍
总结:
使用子查询和关联查询,一般情况下如果能用关联查询就不用子查询,
项目中采用Hibernate的运行缓慢,一面时我们对于Hibernate的API掌握的不够,另外一方面原因是因为他自动生产的子查询的原因可能也产生一部原因把。所以我自己写SQL时禁止使用子查询尽可能的使用关联查询,提供自己的查询效率。
以为数据库人员的blog,很值得去看的!
http://www.cnblogs.com/zping/