论坛首页 Java企业应用论坛

用n+1句sql解决多表查询反而比1句联合sql要好

浏览 24706 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-10-19  
ytrgmj 写道
抛出异常的爱 写道
你以为网络传输是白送的?

n+1的确在网络方面会多耗一点资源,但是我觉得在大部分应用中,这些资源的消耗是可以补偿回来的。相对来说,对db的负担更加减轻了

跑N个sql是啥概念。普通情况下单个sql比多个快。
0 请登录后投票
   发表时间:2011-10-19  
分页可以做在学生表上,然后再连接老师表嘛
0 请登录后投票
   发表时间:2011-10-19  
CurrentJ 写道
ytrgmj 写道
抛出异常的爱 写道
你以为网络传输是白送的?

n+1的确在网络方面会多耗一点资源,但是我觉得在大部分应用中,这些资源的消耗是可以补偿回来的。相对来说,对db的负担更加减轻了

跑N个sql是啥概念。普通情况下单个sql比多个快。

其实存在分页的情况下,反而是多个sql快,你可以测试一下我在主贴里面说的那种情况。
但是的确会多消耗一些网络带宽,因为要传递n+1个sql给数据库 并从数据库读取n+1个记录集回来。
总的来说:这减轻了数据库的负担,增加了网络的负担。
但从总的来看,这个还是划算的。因为网络负担增加的不多,而数据库负担减少了很多。
可以用sql server的性能分析器看看这两种写法对db的负担。
0 请登录后投票
   发表时间:2011-10-19  
czwlucky 写道
分页可以做在学生表上,然后再连接老师表嘛

这就是n+1条sql查询的实际情况,因为分页在学生表里面做了,数据库不会在学生表×老师表的空间中寻找符合查询条件的。
0 请登录后投票
   发表时间:2011-10-19   最后修改:2011-10-19
抛出异常的爱 写道
CurrentJ 写道
weifly 写道
抛出异常的爱 写道
你以为网络传输是白送的?


select * from 老师表 where tid in (t1, t2, t3 ... tn)

1 + 1 sql,网络也不成问题了

然后在内存里把老师再对应到每个学生上。

好吧 你是打算 用hibernate。


第一种情况需要连接数据库1+N次,后一种只需要1次,大数据量情况下仍不宜采用第一种方案。
0 请登录后投票
   发表时间:2011-10-19  
hhsc00 写道
抛出异常的爱 写道
CurrentJ 写道
weifly 写道
抛出异常的爱 写道
你以为网络传输是白送的?


select * from 老师表 where tid in (t1, t2, t3 ... tn)

1 + 1 sql,网络也不成问题了

然后在内存里把老师再对应到每个学生上。

好吧 你是打算 用hibernate。


第一种情况需要连接数据库1+N次,后一种只需要1次,大数据量情况下仍不宜采用第一种方案。

一W条不算什么,上百万上千万条效果差距就很明显了


问题在于,链接n+1次对数据库的性能反而比较低,尤其是上百万上千万的情况。
各位不信,可以自己写代码实现一下。如果两个表都是百万情况下,用n+1的页面肯定能出来,用一条sql联合查询 肯定出不来。

0 请登录后投票
   发表时间:2011-10-19  
大伙有点想当然了,觉得n+1肯定比1条慢,其实未必。
0 请登录后投票
   发表时间:2011-10-19  
n+1的话,比select子查询有何优势?
0 请登录后投票
   发表时间:2011-10-19  
gtssgtss 写道
n+1的话,比select子查询有何优势?

总的来说, 绝对同样的操作,肯定是一条sql快。
但是存在分页的情况下,n+1和联合查询其实并不是同样的操作,虽然他们的结果是一样的。
n+1的本质是 先在学生表里面查询好记录集,然后分页,再去当前的数据查询老师表。
而一条sql语句的联合查询,本质上将老师表和学生表联合查询后,再进行分页。
实际上两者的分页的顺序是不一样,这就造成了一个问题,第一种只要拿一页的记录去老师表里面查询就可以,而联合查询是将学生表里面的所有记录去老师表查询一次。所以两者的性能差距可能是上千级别的。
当表的数据很少的时候,无论用何种方法都可以出来结果。但是当表的数据比较大,比如老师表和学生表都有上百万条的时候,反而是n+1这种解决方案更好。
为什么发这个帖子,是看到很多人发帖说做了一种方案能够解决n+1问题,但是实际上,这种努力是白费的,因为面对大数据量,反而是n+1的解决方案更符合实际。
0 请登录后投票
   发表时间:2011-10-19  
ytrgmj 写道
gtssgtss 写道
n+1的话,比select子查询有何优势?

总的来说, 绝对同样的操作,肯定是一条sql快。
但是存在分页的情况下,n+1和联合查询其实并不是同样的操作,虽然他们的结果是一样的。
n+1的本质是 先在学生表里面查询好记录集,然后分页,再去当前的数据查询老师表。
而一条sql语句的联合查询,本质上将老师表和学生表联合查询后,再进行分页。
实际上两者的分页的顺序是不一样,这就造成了一个问题,第一种只要拿一页的记录去老师表里面查询就可以,而联合查询是将学生表里面的所有记录去老师表查询一次。所以两者的性能差距可能是上千级别的。
当表的数据很少的时候,无论用何种方法都可以出来结果。但是当表的数据比较大,比如老师表和学生表都有上百万条的时候,反而是n+1这种解决方案更好。
为什么发这个帖子,是看到很多人发帖说做了一种方案能够解决n+1问题,但是实际上,这种努力是白费的,因为面对大数据量,反而是n+1的解决方案更符合实际。


你想说没有索引时执行计划?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics