设为首页收藏本站
查看: 122|回复: 0

[PHP] sqlservernotin语句使程充崩溃

[复制链接]

论坛元老

Rank: 6Rank: 6

积分
34274
主题
17031
UID
1347
M币
67
贡献
17176

  • 发表于 2018-7-14 20:53:00 | 显示全部楼层 |阅读模式
    以前一直以为优化在百万级的表中才会有意义,这次的事件改变了我的看法

    两张表 组织架构表(Organise) 和 工资发放历史记录表 (WagePerMonthHis)
    两张表通过 Organise.Item_id 和 WagePerMonthHis.OrgIdS 进行关联
    Organise表(以下简称O表)中大约有6000条记录11个字段 ,WagePerMonthHis(以下简称W表)计有 125万条记录 和 25个字段
    原程序中一段如下的语句
    是查询所有不在W表的组织架构层级为2的记录
    代码如下:
    select OrgId as 公司编码,OrgName as 公司名称
    from Organise
    where OrgLev=2
    and item_id not in
    (select OrgidS from WagesPerMonthHis
    where WagesYear='2010' and WagesMOnth=
    '01' Group by OrgidS,OrgNameS)
    order by Orgid 语句执行要33秒之久,服务器的配置是比较高的:16核心4CPU,24G内存,且内存和CPU在执行时都没有出现瓶颈,开始以为是 (select OrgidS from WagesPerMonthHis
    where WagesYear='2010' and WagesMOnth=
    '01' Group by OrgidS,OrgNameS) 这条语句执行缓慢所致,单独执行这条却发现执行速度很快,大约不到2秒就出来了,于是症结出来了,是not in 这个全扫描关键词带来的性能下降.最直接的是导致页面失去响应,一个关键功能使用不了.
    试了not exist语句,发现效果是一样的,并不象网上所说可以提高很多性能.
    于是重新优化语句如下
    代码如下:
    select a.OrgId as 公司编码,a.OrgName as 公司名称,a.item_id
    from Organise a
    left outer join (select distinct b.OrgIdS from WagesPerMonthHis b
    where WagesYear='2010' and WagesMOnth='01') as b
    on a.item_id = b.OrgidS
    where a.OrgLev = 2
    and b.OrgIdS is Null
    order by 公司编码 改用左外连接(其实左连接也可以)后,整个语句执行速度为400ms, 33秒与400ms 我想是很多人没想到的.
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    在我站开通SVIP可同时获得17个站点VIP资源 立即登录 立即注册
    快速回复 返回顶部 返回列表