V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
zrp1994
V2EX  ›  MySQL

SQL 使用 Join 好还是多次 Select 好?

  •  
  •   zrp1994 · 2015-05-29 10:17:50 +08:00 · 16381 次点击
    这是一个创建于 3467 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在做一个有关地理位置的应用,涉及到的逻辑比较复杂。其中一个表用于存储传感器的基本信息,另一个表存储传感器获得的数据点(这个表的数据相对于其他表来说比较大)。
    为了获得用户所拥有的每一个传感器最近一次的数据的列表,我是用了一个带有多个JOIN的语句,并且用Group by来合并同一个传感器的数据,以此来找到每个传感器最近一条数据。但是现在有了几万条数据之后感觉查询有些慢。。。
    大家认为这种情况下是使用Join好还是分开多次Select更好呢?
    新手求轻喷……

    30 条回复    2015-06-14 17:46:22 +08:00
    slixurd
        1
    slixurd  
       2015-05-29 10:36:46 +08:00   ❤️ 1
    如果是为了让别人容易看懂可以分开多次select,每个select都写的尽可能简单,这样比较容易维护
    不过用运行时间空间做标准的话,还是JOIN比较好,不过记得用子查询,不然笛卡尔积太大速度一样很慢
    iam36
        2
    iam36  
       2015-05-29 10:40:34 +08:00   ❤️ 1
    看过滤条件,只要有(就是where啦),肯定分开差效率高。

    数据达到一定量级后结果就会有极大的差别
    b821025551b
        3
    b821025551b  
       2015-05-29 10:42:33 +08:00   ❤️ 1
    按照where落点数据的前几个字段做索引看看还慢不慢
    yangqi
        4
    yangqi  
       2015-05-29 10:45:36 +08:00   ❤️ 1
    join肯定比多次select要好,当然前提是表和语句要优化好
    zrp1994
        5
    zrp1994  
    OP
       2015-05-29 10:46:26 +08:00
    @slixurd 确实有用子查询,但是主要是SQL Server的group by什么的和MySQL很不一样,所以加了好几个join和子查询,感觉对效率不放心,看样子还是要从现有的语句进行优化呀~
    zrp1994
        6
    zrp1994  
    OP
       2015-05-29 10:47:18 +08:00
    @iam36 嗯,有用到一些where和in,我觉着速度慢也有可能是in的问题
    liprais
        7
    liprais  
       2015-05-29 10:50:36 +08:00   ❤️ 1
    不知道你用的什么数据库,
    如果是商业数据库的话,join基本上能优化的很好了,至少比你自己拆的好
    mysql倒是不一定了。
    p.s 一定要收集统计信息!
    zrp1994
        8
    zrp1994  
    OP
       2015-05-29 10:55:35 +08:00
    @liprais 谢谢提醒O(∩_∩)O
    otakustay
        9
    otakustay  
       2015-05-29 11:06:49 +08:00
    如果你的数据量会提升到需要分表甚至分库的程度,建议减少join。一但分表分库,join就玩不成了
    zrp1994
        10
    zrp1994  
    OP
       2015-05-29 11:08:56 +08:00
    @otakustay 这个也是有可能的,如果真到那个地步了就要好好搞下缓存什么的了~~~
    FifiLyu
        11
    FifiLyu  
       2015-05-29 11:28:33 +08:00
    正在维护别人写的程序。sql慢查询非常多,我只想说:“能不能分开查询?不要用这么多join之类的联表查询?”

    基本10个人访问页面,mysql就跑到600%左右的。哎!
    zhouquanbest
        12
    zhouquanbest  
       2015-05-29 11:30:43 +08:00   ❤️ 1
    实习时发现的第一件事就是不让使用join
    exuxu
        13
    exuxu  
       2015-05-29 11:36:00 +08:00   ❤️ 1
    心理想着select,敲着成了delete
    Conte
        14
    Conte  
       2015-05-29 11:37:03 +08:00
    =。= 新手什么的公司才不会让你用join 分分钟搞死一些东西
    Conte
        15
    Conte  
       2015-05-29 11:37:18 +08:00
    @Conte 我是对自己说的哈
    huijiewei
        16
    huijiewei  
       2015-05-29 11:41:53 +08:00
    以前沉迷于使用复杂的 SQL 语句,现在还是喜欢把复杂的东西分拆为几个简单的。
    loveyu
        17
    loveyu  
       2015-05-29 12:18:00 +08:00
    一般我如果有索引且不复杂的SQL直接join,复杂点的就分吧。当然看统计
    Cloudee
        18
    Cloudee  
       2015-05-29 14:52:44 +08:00 via iPhone
    explain一下看看执行计划,join的话一不小心就循环起来了
    caoyue
        19
    caoyue  
       2015-05-29 18:51:34 +08:00
    既然是用SQL Server ,查询分析器还是用起来吧
    bitzhuxb
        20
    bitzhuxb  
       2015-05-29 19:46:47 +08:00   ❤️ 1
    感觉很简单呀~
    做一个 子查询 计算出每个传感器的最近一条数据。
    再做一个子查询 计算出 用户的所有传感器

    然后利用 然后这两个子查询进行join. 两个子查询量已经很小了
    koodai
        21
    koodai  
       2015-05-29 20:45:30 +08:00 via iPhone
    join在mysql下性能差,不推荐,我在阿里云数据库的体验,子查询要极大提高性能。
    原因不明所以。
    zrp1994
        22
    zrp1994  
    OP
       2015-05-29 20:51:49 +08:00
    @bitzhuxb 好主意
    zrp1994
        23
    zrp1994  
    OP
       2015-05-29 20:55:23 +08:00
    @bitzhuxb 其实我是这么做的,但是SQL Server里面的GROUP实在是搞不懂。。。和MySQL差太多了
    coolcfan
        24
    coolcfan  
       2015-05-29 21:32:37 +08:00
    我是跑测试的,不懂这块的具体技术细节,但是用 MySQL 的话,explain 一下,看到给出的那个表格里要是写了需要创建临时表的标记,那并发高一点 CPU 占用会很恐怖。
    zonghua
        25
    zonghua  
       2015-05-29 23:05:49 +08:00 via iPhone
    @huijiewei 就是不依靠数据库,由应用?
    mingyun
        26
    mingyun  
       2015-06-07 16:35:05 +08:00
    楼主现在采用什么方案?有用吗
    zrp1994
        27
    zrp1994  
    OP
       2015-06-08 09:33:39 +08:00
    @mingyun 暂时还是join,正在考虑加redis缓存经常查询的结果
    zonghua
        28
    zonghua  
       2015-06-12 00:42:08 +08:00
    @koodai 哪里可以得到测试数据来验证自己的语句呢?我想学习一下。
    mingyun
        29
    mingyun  
       2015-06-14 11:46:52 +08:00
    @FifiLyu 不至于吧,连了很多表?
    FifiLyu
        30
    FifiLyu  
       2015-06-14 17:46:22 +08:00
    @mingyun 最多4个表。表数据基本都是10多万行。基于运维这边,不好优化啊。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2757 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 06:32 · PVG 14:32 · LAX 22:32 · JFK 01:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.