V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xliao
V2EX  ›  数据库

大家怎么看子查询作为 Select column 的 SQL?

  •  
  •   xliao · 2017-05-20 17:24:36 +08:00 · 1836 次点击
    这是一个创建于 2776 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近接手的一个项目中几乎所有多表查询的 SQL 都是这种写法,请大家从规范、可维护性、可读性……各种方面来进行吐槽也好,点赞也好,感谢你的留言!

    SELECT
    	t.user_id,
    	t.org_id,
    	t.user_account,
    	t.user_name,
    	t.mobile,
    	t.sex,
    	t.role_id,
    	(
    		SELECT
    			r.role_name
    		FROM
    			sys_role r
    		WHERE
    			r.role_id = t.role_id
    	) roleName,
    	(select xx from where ...) xxx,
    	(select yy from where ...) yyy,
    FROM
    	sys_user t
    WHERE
    	...
    

    另外还有种 SQL 出现频次比较高:明明可以直接关联查询的,还是各种 LEFT JOIN ON

    第 1 条附言  ·  2017-05-21 01:05:40 +08:00
    一一看了大家的回复,现在这种写法其实已经出现性能问题了,甚至出错。
    1、出现了几次子查询做 select column 数据不唯一导致整个功能报错的情况了
    2、表关联较多(跟当初设计有关),几张常用的表相关的业务查询慢的问题已经开始频繁爆发
    3、表设计问题,梳理的时候发现一些该有的索引都没有建
    4、可以直接关联并根据条件过滤或者约束查询结果的,却使用 LEFT JOIN 查询多余的结果
    11 条回复    2017-05-21 06:36:10 +08:00
    blueskit
        1
    blueskit  
       2017-05-20 18:07:33 +08:00 via Android
    逻辑更清楚,更难被优化,效率更低
    noNOno
        2
    noNOno  
       2017-05-20 18:09:31 +08:00
    子查询作为 Select column,就可以在 sys_role 表里控制字段名以及字段处理规则。
    annielong
        3
    annielong  
       2017-05-20 18:17:08 +08:00
    各有优缺点,看具体项目情况而定,
    billlee
        4
    billlee  
       2017-05-20 19:06:24 +08:00
    这种很难被优化,但是 LEFT JOIN 有什么问题吗?
    mhycy
        5
    mhycy  
       2017-05-20 20:48:09 +08:00
    记忆中,在 MYSQL 中 JOIN 的性能很多时候不如子查询,这和查询优化器的实现有关系
    woshixiaohao1982
        6
    woshixiaohao1982  
       2017-05-20 21:03:44 +08:00
    优点可读性好吧,效率低在哪里 我不好分析,因为写 SQL 大多都有一种 喜欢函数返回 做子查询,这种带状态的 SQL
    一来是写起来比较方便,而来是容器理解,你说 join 来 join 去,说实话,join 是很难 一下子看出个所以来的,
    而且复杂的 SQL 通常要手工测试好几遍,才能得到正确的 SQL
    onikage
        7
    onikage  
       2017-05-20 21:29:42 +08:00 via iPhone
    oracle 上几十万的表以前经常这样玩(子查询做 column ),没觉得有啥性能问题,还是在我自己的笔记本的虚拟机上执行的。
    tjxjj
        8
    tjxjj  
       2017-05-20 22:02:25 +08:00
    总体来说,肯定是连接查询效率要高

    但是,看情况,如果就查询结果就一条记录,这样就挺好

    SQL 优化一个原则 ,看结果,如果最终效率可以接受,就没必要去优化了.
    l00t
        9
    l00t  
       2017-05-20 23:15:51 +08:00
    这种写法性能问题比较严重吧。项目里一直这么写,没遇到性能上的障碍吗?

    LEFT JOIN 和 直接关联的查询,语义上都不一样了,这个怎么比。
    noark9
        10
    noark9  
       2017-05-20 23:26:13 +08:00
    根据业务需求和性能平衡吧,一般如果需要查询的字段很少(一个,两个)并且通过是可以通过唯一索引在子查询查到的话,那么可以考虑用子查询,如果需要获取的字段很多的话,那么建议还是去 join 吧,另外这么说也并不是完全正确,具体还是是需要根据执行计划来优化,平衡内存和时间的消耗
    msg7086
        11
    msg7086  
       2017-05-21 06:36:10 +08:00   ❤️ 2
    用惯了 Rails 以后已经养成了尽量少用复杂语句的习惯了。
    数据库你只有一两台,App 服务器倒是可以部署一大堆,何必把大量的逻辑处理部分推给数据库呢。

    像楼主这个查询,分成 4 个单独的查询,然后让 ORM 负责组合,会大大降低服务器的负载。
    特别是近年来 MySQL 的查询缓存已经默认打开了,很多附属表的单独查询可以直接从缓存返回,比 JOIN 读表要快。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3819 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 05:08 · PVG 13:08 · LAX 21:08 · JFK 00:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.