类似的查询,可能会很多,例如:
userInfo表结构为:
id | user_id | name | code | val |
1 | 35 | 王五 | age | 22 |
2 | 35 | 王五 | mobile | 18612341234 |
3 | 35 | 王五 | idno | 331228198501024423 |
- | - | - | - | - |
4 | 37 | 王六 | age | 19 |
5 | 37 | 王六 | mobile | 13212341234 |
6 | 37 | 王六 | idno | null |
- | - | - | - | - |
8 | 39 | 王七 | age | 18 |
9 | 39 | 王七 | mobile | 18612341234 |
10 | 39 | 王七 | idno | 13312341234 |
查询
年龄>18
手机号不为空
哪些人没填写身份证号
正确的查询结果是“王六”
三条语句,完成同样的查询功能,执行效率对比
表结构
第一种写法,使用exists进行查询
select count(*) from pis_checkitemindexresult c where exists (select 1 from pis_checkitemindexresult c2 where c2.itemindexmiscode = '1.2.4.1' --身高 and f_is_num(c2.itemindexresultvalue) = 'T' and c2.workno = c.workno) and exists (select 1 from pis_checkitemindexresult c3 where c3.itemindexmiscode = '1.2.4.2' --体重 and f_is_num(c3.itemindexresultvalue) = 'T' and c3.workno = c.workno) and c.itemindexmiscode = '1.2.4.3' --体重指数 and c.itemindexresultvalue is null
PLSQL执行计划:
第二种写法,使用count(*)来查询
select count(*) from pis_checkitemindexresult c where (select count(*) from pis_checkitemindexresult c2 where c2.itemindexmiscode = '1.2.4.1' --身高 and f_is_num(c2.itemindexresultvalue) = 'T' and c2.workno = c.workno) > 0 and (select count(*) from pis_checkitemindexresult c3 where c3.itemindexmiscode = '1.2.4.2' --体重 and f_is_num(c3.itemindexresultvalue) = 'T' and c3.workno = c.workno) > 0 and c.itemindexmiscode = '1.2.4.3' --体重指数 and c.itemindexresultvalue is null
PLSQL执行计划:
第三种写法:使用inner join来关联查询
select count(*) from pis_checkitemindexresult c inner join pis_checkitemindexresult c2 on c.workno = c2.workno inner join pis_checkitemindexresult c3 on c.workno = c3.workno where c2.itemindexmiscode = '1.2.4.1' and f_is_num(c2.itemindexresultvalue)='T' and c3.itemindexmiscode = '1.2.4.2' and f_is_num(c3.itemindexresultvalue)='T' and c.itemindexmiscode = '1.2.4.3' and c.itemindexresultvalue is null
PLSQL执行计划:
问题是哪种方法执行效率最高,现在每个都10分钟都执行不完。