mysql子查询复杂操作,mysql 联表操作及子查询操作注意点

背景:写了一个左联表修改表的sql语句,中间包含了子查询;让同事帮忙评审后,做了些修改,并给了我很重要的建议

1.能不用子查询的尽量不用子查询,将sql结构调整成不含子查询的

2.有些情况可以考虑自连接

3.在使用左右连接的时候,一定要考虑到左右表的区别,决定是应用左联还是右联

修改前sql

UPDATE ecm_goods_status AS egs

LEFT JOIN (

SELECT goods_id,ONLINE,ma_type

FROM

ecm_market_activity_apply

WHERE

goods_id IN (SELECT goods_id FROM ecm_goods_status WHERE if_stock = 1)

AND STATUS = 2

AND ma_type IN (21)

) AS emaa ON egs.goods_id = emaa.goods_id

SET egs.if_stock = emaa.ONLINE修改后sql

UPDATE ecm_goods_status AS egs,ecm_market_activity_apply AS emaa

SET egs.if_stock = emaa.ONLINE

WHERE egs.goods_id=emaa.goods_id AND egs.goods_id=egs.goods_id

AND emaa.STATUS=2 AND emaa.ma_type IN(21) AND egs.if_stock=1

修改前的sql存在问题:

1.选择左联接是错误的,这样会修改ecm_goods_status表的所有if_stock字段值(左联数据以左表为准,没有结果的以null填充)。应该改成右联,这样修改的字段以右临时表的数据记录数为准。

2.存在字查询和临时表,如果转成select语句,explain一下可以如

EXPLAIN SELECT * FROM ecm_goods_status AS egs

-- UPDATE ecm_goods_status AS egs

RIGHT JOIN (

SELECT goods_id,ONLINE,ma_type

FROM ecm_market_activity_apply

WHERE

goods_id IN (SELECT goods_id FROM ecm_goods_status WHERE if_stock = 1)

AND STATUS = 2

AND ma_type IN (21)

) AS emaa ON egs.goods_id = emaa.goods_id

-- SET egs.if_stock = emaa.ONLINE

ddebc039c67288ac7c396075cdfee3e8.png

修改后的sql变成select语句,explain后

EXPLAIN SELECT * FROM ecm_goods_status AS egs,ecm_market_activity_apply AS emaa

WHERE egs.goods_id=emaa.goods_id AND egs.goods_id=egs.goods_id AND emaa.STATUS=2

AND emaa.ma_type IN(21) AND egs.if_stock=1;

02622377ecbcf57a0c0ea3397c34fafb.png

可以发现运行的步骤变得更少,sql语句也更简洁了。

总结:

1.在以后遇到联表操作时需要考虑到左右联时考虑表位置的放置

2.遇到子查询的场景时,尽量想办法避免(子查询内的语句是不会走索引的,当子查询涉及的表数据量很大时,没有索引很可能会让差些的sql服务器宕掉)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值