菜鸟日记(2013-5-8)-关于两句SQL语句得到的启示
来源:互联网 发布:软件开发服务税率 编辑:程序博客网 时间:2024/04/28 07:18
这个是第一个语句:
SELECT * from T_CarInfo
where T_CarInfo.CarID not in (
SELECT
T_RepairBill.CarID
FROM
T_RepairBillRepairType
LEFT JOIN T_RepairBill
ON T_RepairBillRepairType.RepairBillCode = T_RepairBill.RepairBillCode AND T_RepairBillRepairType.PointCode = T_RepairBill.PointCode
LEFT JOIN T_ComParameter
ON T_RepairBillRepairType.RepairType=T_ComParameter.ParameterFlag and T_RepairBillRepairType.PointCode=T_ComParameter.PointCode
where T_ComParameter.MaintenanceFlag=1
AND
(T_RepairBillRepairType.PointCode IN (SELECT PointCode FROM DBO.F_GetRelationPointCollection('0', 1, 1, -1 * ISNULL(0, 0), 1)))
)
and (T_CarInfo.PointCode IN (SELECT PointCode FROM DBO.F_GetRelationPointCollection('0', 1, 1, -1 * ISNULL(0, 0), 1)))
这个是第二个语句:
SELECT * from T_CarInfo
where NOT exists(
SELECT
1
FROM
T_RepairBillRepairType
LEFT JOIN T_RepairBill
ON T_RepairBillRepairType.RepairBillCode = T_RepairBill.RepairBillCode AND T_RepairBillRepairType.PointCode = T_RepairBill.PointCode
LEFT JOIN T_ComParameter
ON T_RepairBillRepairType.RepairType=T_ComParameter.ParameterFlag and T_RepairBillRepairType.PointCode=T_ComParameter.PointCode
where T_ComParameter.MaintenanceFlag=1
AND T_RepairBill.CarID=T_CarInfo.CarID
AND
(T_RepairBillRepairType.PointCode IN (SELECT PointCode FROM DBO.F_GetRelationPointCollection('0', 1, 1, -1 * ISNULL(0, 0), 1)))
)
and (T_CarInfo.PointCode IN (SELECT PointCode FROM DBO.F_GetRelationPointCollection('0', 1, 1, -1 * ISNULL(0, 0), 1)))
查询出来的结果无疑第二句是正确的,第一句是空的。
我不明白的是第一个语句与第二个语句所要表达的意义是一样的,都是排除T_ComParameter.MaintenanceFlag=1
这种情况下的数据信息。为什么第一个语句查询的是空的呢?
我把子查询拿出来执行了一下:
SELECT row_number() over(order by T_RepairBill.CarID), T_RepairBill.CarID
FROM
T_RepairBillRepairType
LEFT JOIN T_RepairBill
ON T_RepairBillRepairType.RepairBillCode = T_RepairBill.RepairBillCode AND T_RepairBillRepairType.PointCode = T_RepairBill.PointCode
LEFT JOIN T_ComParameter
ON T_RepairBillRepairType.RepairType=T_ComParameter.ParameterFlag and T_RepairBillRepairType.PointCode=T_ComParameter.PointCode
where T_ComParameter.MaintenanceFlag=1
--and T_RepairBill.RepairBillCode is not null
像这样得到数据确实有空的存在。毕竟T_RepairBill 不是主表,存在空的CarID也是很正常的。
那么有空的CarID是否有影响呢,答案是肯定的。
原因是这样的:
IN或NOT IN就是几个OR的联合where a NOT IN(1,2,3)就是where a=1 or a=2 or a=3而对NULL值的判断是用IS NULL,IS NOT NULL来的写A=NULL或者A!=NULL肯定是没结果的
对比着两种的Sql写法,就不由自主的对比EXists与in 的优略性。这里有一段文字关于两种写法的对比:
(
in和exists执行时,in是先执行子查询中的查询,然后再执行主查询。而exists查询它是先执行主查询,即外层表的查询,然后再执行子查询。
exists 和 in 在执行时效率单从执行时间来说差不多,exists要稍微优于in。在使用时一般应该是用exists而不用in
如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in,反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。IN时不对NULL进行处理。
not exists 和 not in 比较时,not exists 的效率比较高。
为了说明测试结果,我把emp1表中的数据到了315392条。emp2中删除只有2条件数据。测试的依据是执行的时间来说明的。
emp1中的数据记录情况。
SQL> select count(*) from emp1;
COUNT(*)
----------
315392
emp2中的数据记录情况:
SQL> select count(*) from emp2;
COUNT(*)
----------
2
1、 执行exists查询,要求在emp1中查询出所有存在于emp2的数据总数
SQL> select count(*) from emp1 where exists ( select null from emp2 where emp1.ename = emp2.ename);
COUNT(*)
----------
45056
执行次数十次,最大的一次为0.125S
2、 使用not exists查询出所在不在emp2中的数据总数
SQL> select count(*) from emp1 where not exists ( select null from emp2 where emp1.ename = emp2.ename);
COUNT(*)
----------
270336
执行次数十次,最大的一次为0.141S
3、执行in 查询,要求在emp1中查询出所有存在于emp2的数据总数
SQL> select count(*) from emp1 where ename in ( select ename from emp2);
COUNT(*)
----------
45056
执行十次,最大的一次为0.141S
4、使用not in查询出所在不在emp2中的数据总数
SQL> select count(*) from emp1 where ename not in ( select ename from emp2 );
COUNT(*)
----------
270336
执行十次,最长一次为0.328S
5、使用in查询,调用外层与子查询的位置,要求查询出存在于emp2中,且存在于emp1中的数据记录数
SQL> select count(*) from emp2 where ename in (select ename from emp1 );
COUNT(*)
----------
2
执行次数十次,最长的一次为0.047S
6、使用exists查询,调用外层与子查询的位置,要求查询出存在于emp2中,且存在于emp1中的数据记录数
SQL> select count(*) from emp2 where ename in (select ename from emp1 );
COUNT(*)
----------
2
执行次数十次,最长的一次为0.047S
综上所述:在使用in 和 exists时,个人觉得,效率差不多。而在not in 和 not exists比较时,not exists的效率要比not in的效率要高。
当使用in时,子查询where条件不受外层的影响,自动优化会转成exist语句,它的效率和exist一样。(没有验证)
如select * from t1 where f1 in (select f1 from t2 where t2.fx='x') 这时,认为in 和 exists效率一样。
IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
)
- 菜鸟日记(2013-5-8)-关于两句SQL语句得到的启示
- 两句话的启示
- 得到SQL SERVER DB SCHEMA 的SQL語句
- 冰箱中得到的启示
- 由跑步得到的启示
- 菜鸟学习日记:关于scolltop的问题
- 新手的50句SQL语句
- 两条关于生成排名的SQL语句
- 关于公司部门的SQL语句,两问
- 关于级别表的两例常用sql语句
- SQL 维护用得到的监控语句
- 菜鸟前端日记5(原生JS--流程控制语句)
- 得到SQL语句执行时间
- 程序员应聘中得到的启示
- 由方法得到的一点小启示
- 从“O2O演唱会”中得到的启示
- 从父亲那得到的启示
- 从龙虱得到的启示
- Android振动器(Vibrator)系统详解
- LIB和DLL的区别与使用
- varnish工作原理详细讲解
- HOOK使用:全局键盘钩子
- mini2440烧写裸机程序(MDK+Jlink)
- 菜鸟日记(2013-5-8)-关于两句SQL语句得到的启示
- cocoStudio骨骼动画之代码实现
- 高效程序员的 7 个共同特征
- 一些比较好的调试案例
- 表格背景图片居中
- UML图总结
- linux设备驱动归纳总结(三):7.异步通知fasync
- cocos2d-x 1.0 2.0 代码差异
- openstack扩展API