精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-10-19
ytrgmj 写道 抛出异常的爱 写道 你以为网络传输是白送的?
n+1的确在网络方面会多耗一点资源,但是我觉得在大部分应用中,这些资源的消耗是可以补偿回来的。相对来说,对db的负担更加减轻了 跑N个sql是啥概念。普通情况下单个sql比多个快。 |
|
返回顶楼 | |
发表时间:2011-10-19
分页可以做在学生表上,然后再连接老师表嘛
|
|
返回顶楼 | |
发表时间:2011-10-19
CurrentJ 写道 ytrgmj 写道 抛出异常的爱 写道 你以为网络传输是白送的?
n+1的确在网络方面会多耗一点资源,但是我觉得在大部分应用中,这些资源的消耗是可以补偿回来的。相对来说,对db的负担更加减轻了 跑N个sql是啥概念。普通情况下单个sql比多个快。 其实存在分页的情况下,反而是多个sql快,你可以测试一下我在主贴里面说的那种情况。 但是的确会多消耗一些网络带宽,因为要传递n+1个sql给数据库 并从数据库读取n+1个记录集回来。 总的来说:这减轻了数据库的负担,增加了网络的负担。 但从总的来看,这个还是划算的。因为网络负担增加的不多,而数据库负担减少了很多。 可以用sql server的性能分析器看看这两种写法对db的负担。 |
|
返回顶楼 | |
发表时间:2011-10-19
czwlucky 写道 分页可以做在学生表上,然后再连接老师表嘛
这就是n+1条sql查询的实际情况,因为分页在学生表里面做了,数据库不会在学生表×老师表的空间中寻找符合查询条件的。 |
|
返回顶楼 | |
发表时间:2011-10-19
最后修改:2011-10-19
抛出异常的爱 写道 CurrentJ 写道 weifly 写道 抛出异常的爱 写道 你以为网络传输是白送的?
select * from 老师表 where tid in (t1, t2, t3 ... tn) 1 + 1 sql,网络也不成问题了 然后在内存里把老师再对应到每个学生上。 好吧 你是打算 用hibernate。 第一种情况需要连接数据库1+N次,后一种只需要1次,大数据量情况下仍不宜采用第一种方案。 |
|
返回顶楼 | |
发表时间: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联合查询 肯定出不来。 |
|
返回顶楼 | |
发表时间:2011-10-19
大伙有点想当然了,觉得n+1肯定比1条慢,其实未必。
|
|
返回顶楼 | |
发表时间:2011-10-19
n+1的话,比select子查询有何优势?
|
|
返回顶楼 | |
发表时间:2011-10-19
gtssgtss 写道 n+1的话,比select子查询有何优势?
总的来说, 绝对同样的操作,肯定是一条sql快。 但是存在分页的情况下,n+1和联合查询其实并不是同样的操作,虽然他们的结果是一样的。 n+1的本质是 先在学生表里面查询好记录集,然后分页,再去当前的数据查询老师表。 而一条sql语句的联合查询,本质上将老师表和学生表联合查询后,再进行分页。 实际上两者的分页的顺序是不一样,这就造成了一个问题,第一种只要拿一页的记录去老师表里面查询就可以,而联合查询是将学生表里面的所有记录去老师表查询一次。所以两者的性能差距可能是上千级别的。 当表的数据很少的时候,无论用何种方法都可以出来结果。但是当表的数据比较大,比如老师表和学生表都有上百万条的时候,反而是n+1这种解决方案更好。 为什么发这个帖子,是看到很多人发帖说做了一种方案能够解决n+1问题,但是实际上,这种努力是白费的,因为面对大数据量,反而是n+1的解决方案更符合实际。 |
|
返回顶楼 | |
发表时间:2011-10-19
ytrgmj 写道 gtssgtss 写道 n+1的话,比select子查询有何优势?
总的来说, 绝对同样的操作,肯定是一条sql快。 但是存在分页的情况下,n+1和联合查询其实并不是同样的操作,虽然他们的结果是一样的。 n+1的本质是 先在学生表里面查询好记录集,然后分页,再去当前的数据查询老师表。 而一条sql语句的联合查询,本质上将老师表和学生表联合查询后,再进行分页。 实际上两者的分页的顺序是不一样,这就造成了一个问题,第一种只要拿一页的记录去老师表里面查询就可以,而联合查询是将学生表里面的所有记录去老师表查询一次。所以两者的性能差距可能是上千级别的。 当表的数据很少的时候,无论用何种方法都可以出来结果。但是当表的数据比较大,比如老师表和学生表都有上百万条的时候,反而是n+1这种解决方案更好。 为什么发这个帖子,是看到很多人发帖说做了一种方案能够解决n+1问题,但是实际上,这种努力是白费的,因为面对大数据量,反而是n+1的解决方案更符合实际。 你想说没有索引时执行计划? |
|
返回顶楼 | |