当前位置:   article > 正文

SQL查询速度优化_where left

where left

1、使用left join比直接使用where速度快

参考:使用left join比直接使用where速度快的原因

多表使用left join只是把主表里的所有数据查询出来,其他表只查询表中的符合条件的某一条记录,所以速度非常快;而多表使用where内联,是把所有表的数据全查出来,然后进行比对,所以速度非常慢。

使用left join要注意确定哪一张表是主表,如果无法确定主表,则选择哪张表查询的字段最多,就把哪张表作为主表。

示例如下:

使用left join,同样的数据量,时间不到1秒钟!

  1. SELECT a.projectno,MAX(a.projectname) projectname,max(a.projectMoney) projectMoney,
  2. max(a.projectLimitYear) projectLimitYear,max(a.monthcharge) monthcharge,
  3. max(c.orgname) orgname,max(d.businesstypename) businesstypename,max(e.name) name,
  4. max(b.dicvalue) dicvalue,
  5. min(CONVERT(varchar(100),DATEADD("DAY",jbl.DelayDays,jbl.ReportTime),23)) as period,
  6. max(f.fiveleveltype) fiveleveltype,max(a.ProjectInfoId) ProjectInfoId,
  7. max(g.FlowRunId) FlowRunId
  8. FROM
  9. (select ProjectInfoId,ProjectNo,Status,OrgId,TypeID,UserAId,IsDelete,ProjectName,ProjectMoney,ProjectLimitYear,MonthCharge from jt_biz_projectinfo) a
  10. LEFT JOIN
  11. (select b.* from (select MAX(id) id, ProjectNo from JT_Biz_Lecture group by ProjectNo) a,
  12. JT_Biz_Lecture b where a.id=b.id) f
  13. on a.projectno=f.projectno
  14. LEFT JOIN
  15. (select DicId,IsDelete,DicValue,DicCode from jt_Base_Dictionary) b
  16. ON a.status=b.dicId
  17. LEFT JOIN
  18. (select ProjectNo,DelayDays,ReportTime from Jt_Biz_LectureTemp) jbl
  19. ON a.projectno=jbl.projectno
  20. LEFT JOIN
  21. (select IsDelete,OrgName,OrgId from jt_base_org) c
  22. ON a.orgid=c.orgid
  23. LEFT JOIN
  24. (select ID,BusinessTypeName from d_businesstype) d
  25. ON a.typeid=d.id
  26. LEFT JOIN
  27. (select UserInfoId,IsDelete,Name,UserName from jt_base_userInfo) e
  28. ON a.useraid=e.userinfoid
  29. LEFT JOIN
  30. (select UserId,PostId,OrgIds from JT_Base_Post_UserOrg) j
  31. ON j.UserId=e.userinfoid
  32. LEFT JOIN
  33. (select PostId from JT_Base_Post) k
  34. ON j.PostId=k.PostId
  35. LEFT JOIN
  36. (select FlowRunId,ProjectId from jt_flow_run) g
  37. ON a.ProjectInfoId=g.ProjectId
  38. LEFT JOIN
  39. (select FlowRunId from JT_Flow_Run_Prcs) h
  40. ON g.FlowRunId = h.FlowRunId
  41. LEFT JOIN
  42. (select OrgId,OrgName from JT_Base_Org) l
  43. ON a.OrgId=l.OrgId
  44. WHERE a.status in(82,83,84) and a.isdelete=0
  45. and b.isdelete=0 and c.isdelete=0 and e.isdelete=0
  46. and (l.OrgId in(null) or e.UserName='chenqf') group by a.ProjectNo;
  1. 不使用left join,同样数据量,时间大概在50秒的样子!
  2. select a.projectno,max(a.projectname) projectname,max(a.projectMoney) projectMoney,
  3. max(a.projectLimitYear) projectLimitYear,max(a.monthcharge) monthcharge,
  4. max(c.orgname) orgname,max(d.businesstypename) businesstypename,max(e.name) name,
  5. max(b.dicvalue) dicvalue,
  6. min(CONVERT(varchar(100),DATEADD("DAY",jbl.DelayDays,jbl.ReportTime),23)) as period,
  7. max(f.fiveleveltype) fiveleveltype,max(a.ProjectInfoId) ProjectInfoId,
  8. max(g.FlowRunId) FlowRunId
  9. from (select DicId,IsDelete,DicValue,DicCode from jt_Base_Dictionary) b,
  10. (select IsDelete,OrgName,OrgId from jt_base_org) c,
  11. (select UserInfoId,IsDelete,Name,UserName from jt_base_userInfo) e,
  12. (select ID,BusinessTypeName from d_businesstype) d,
  13. (select FlowRunId,ProjectId from jt_flow_run) g,
  14. (select FlowRunId from JT_Flow_Run_Prcs) h,
  15. (select UserId,PostId,OrgIds from JT_Base_Post_UserOrg) j,
  16. (select PostId from JT_Base_Post) k,
  17. (select OrgId,OrgName from JT_Base_Org) l,
  18. (select ProjectNo,DelayDays,ReportTime from Jt_Biz_LectureTemp) jbl,
  19. (select ProjectInfoId,ProjectNo,Status,OrgId,TypeID,UserAId,IsDelete,ProjectName,ProjectMoney,ProjectLimitYear,MonthCharge from jt_biz_projectinfo) a
  20. left join
  21. (select b.* from (select MAX(id) id, ProjectNo from JT_Biz_Lecture group by ProjectNo) a,
  22. JT_Biz_Lecture b where a.id=b.id) f
  23. on a.projectno=f.projectno where a.status=b.dicId and a.status in(82,83,84)
  24. and a.projectno=jbl.projectno and a.orgid=c.orgid and a.typeid=d.id
  25. and a.useraid=e.userinfoid and j.UserId=e.userinfoid and a.isdelete=0
  26. and b.isdelete=0 and c.isdelete=0 and e.isdelete=0 and g.FlowRunId = h.FlowRunId
  27. and (l.OrgId in(null) or e.UserName='chenqf')
  28. group by a.ProjectNo;

2、LEFT JOIN关联表中ON,WHERE后面跟条件的区别

写SQL本想通过 A left join B on and 后面的条件来使查出的两条记录变成一条,奈何发现还是有两条。

后来发现  on and 不会过滤结果记录条数,只会根据and后的条件是否显示 B表的记录,A表的记录一定会显示。

不管and 后面的是A.id=1还是B.id=1,都显示出A表中所有的记录,并关联显示B中对应A表中id为1的记录或者B表中id为1的记录。

运行sql : select * from student s left join class c on s.classId=c.id order by s.id

运行sql : select * from student s left join class c on s.classId=c.id and s.name="张三" order by s.id


运行sql : select * from student s left join class c on s.classId=c.id and c.name="三年级三班" order by s.id

       通过查询相关资料了解到:

       数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。

      在使用left jion时,on和where条件的区别如下:

1、 on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。

2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

       假设有两张表:

表1:tab1

表2:tab2

两条SQL:
1、select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’
2、select * form tab1 left join tab2 on (tab1.size = tab2.size and tab2.name=’AAA’)

    

     其实以上结果的关键原因就是left join,right join,full join的特殊性,不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。 而inner jion没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。

3、Where条件中使用主表条件过滤速度较快

  1. SELECT
  2. *
  3. FROM
  4. USER_BORROW T1 -- 数据量2~3万条
  5. LEFT JOIN USER T3 ON T3.OID_USER_ID = T1.OID_USER_ID
  6. LEFT JOIN USER_DETAIL T4 ON T4.OID_USER_ID = T1.OID_USER_ID
  7. LEFT JOIN USER_ARCHIVES T5 ON T5.OID_ARCHIVE_ID = T1.OID_ARCHIVE_ID -- USER_ARCHIVES数据量2~3万条
  8. LEFT JOIN PRODUCT_MST T6 ON T6.OID_PROD_ID = T5.OID_PROD_ID
  9. LEFT JOIN TENANT T7 ON T7.OID_TENANT_ID = T5.OID_TENANT_ID
  10. LEFT JOIN TENANT T8 ON T8.OID_TENANT_ID = T5.OID_TENANT_XS_ID
  11. LEFT JOIN (
  12. SELECT
  13. OID_BORROW_ID,
  14. SUM(REPAY_AMOUNT_TOTAL) AS FEE_AMOUNT
  15. FROM
  16. USER_POUNDAGE_REPAY
  17. WHERE
  18. REPAY_FLG = '0'
  19. GROUP BY
  20. OID_BORROW_ID
  21. ) T9 ON T1.BORROW_ID = T9.OID_BORROW_ID
  22. WHERE
  23. 1 = 1
  24. -- 此处使用T1.OID_TENANT_ID进行数据过滤查询速度很快,
  25. -- 但是使用T5.OID_TENANT_ID进行过滤数据查询速度极慢,不确定是否跟T1为主表有关系???
  26. AND T1.OID_TENANT_ID IN (
  27. SELECT
  28. OT.OID_TENANT_ID
  29. FROM
  30. DEPARTMENT_USER DU
  31. INNER JOIN OPERATOR_TENANT OT ON OT.OID_OPERATOR_USER_ID = DU.OID_ADMIN_USER_ID
  32. WHERE
  33. DU.DEL_FLG = '0'
  34. AND DU.OID_DEPARTMENT_ID = (
  35. SELECT
  36. DU1.OID_DEPARTMENT_ID
  37. FROM
  38. DEPARTMENT_USER DU1
  39. WHERE
  40. DU1.OID_ADMIN_USER_ID = ?
  41. AND DU1.DEL_FLG = '0'
  42. )
  43. )

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/230541
推荐阅读
相关标签
  

闽ICP备14008679号