精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-10-19
学生表的字段为 sid,sname,tid 老师表的字段 为 tid tname 两张表通过tid外键关联。 现在假设一个页面需要浏览学生记录,同时要显示这个学生对应的老师名称,有两种查询方法。 1)一种方法 n+1句sql,先查询select * from 学生表。再根据结果记录查询 select * from 老师表 where tid =? 2)另外一种方法 是建立一条联合查询语句 select * from 学生表 a inner join 老师表 b on a.tid=b.tid。 在没有分页的情况下,第二种方法的效率比第一种方法高,然而在有分页的情况下,反而是n+1句sql的执行效率高。 假设两张表都没有索引,学生表有10000条记录,老师表为1000条记录,每个页面显示100条记录。那么第一种方法数据库的执行的时间复杂度是 10000+100*1000。 第二种方法执行的时间复杂度 是10000×1000。 双方的差别接近1000左右。 在有索引的情况下,双方的差别没有这么大,但也是第一种情况的算法复杂度小。 所以在系统存在分页(绝大部分的系统均存在分页)的情况下,我们还是采取n+1句sql语句进行查询的效率高。 而且第一种方法也是一种扩展性比较良好的方法。假设老师表的数据过多,我们需要把老师表进行水平切割成100个表,那么第一种方法的扩展性是比较好的。第二种方法只有重新修改 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-10-19
这种东西都是看情况才能决定使用何种方式的,没有人敢绝对的下定论
|
|
返回顶楼 | |
发表时间:2011-10-19
liubey 写道 这种东西都是看情况才能决定使用何种方式的,没有人敢绝对的下定论
所以我的前提 是有分页的情况 |
|
返回顶楼 | |
发表时间:2011-10-19
最后修改:2011-10-19
你以为网络传输是白送的?
|
|
返回顶楼 | |
发表时间:2011-10-19
抛出异常的爱 写道 你以为网络传输是白送的?
select * from 老师表 where tid in (t1, t2, t3 ... tn) 1 + 1 sql,网络也不成问题了 |
|
返回顶楼 | |
发表时间:2011-10-19
李华植的《海量数据库解决方案》 第5章 局部范围扫描(partial range scan)
应该有这种拆分,合并的原理解析 http://product.china-pub.com/53793#ml |
|
返回顶楼 | |
发表时间:2011-10-19
抛出异常的爱 写道 你以为网络传输是白送的?
n+1的确在网络方面会多耗一点资源,但是我觉得在大部分应用中,这些资源的消耗是可以补偿回来的。相对来说,对db的负担更加减轻了 |
|
返回顶楼 | |
发表时间:2011-10-19
ytrgmj 写道 抛出异常的爱 写道 你以为网络传输是白送的?
n+1的确在网络方面会多耗一点资源,但是我觉得在大部分应用中,这些资源的消耗是可以补偿回来的。相对来说,对db的负担更加减轻了 网络IO补硬盘IO好吧在极端状态下可以补回来。 |
|
返回顶楼 | |
发表时间:2011-10-19
weifly 写道 抛出异常的爱 写道 你以为网络传输是白送的?
select * from 老师表 where tid in (t1, t2, t3 ... tn) 1 + 1 sql,网络也不成问题了 然后在内存里把老师再对应到每个学生上。 |
|
返回顶楼 | |
发表时间:2011-10-19
CurrentJ 写道 weifly 写道 抛出异常的爱 写道 你以为网络传输是白送的?
select * from 老师表 where tid in (t1, t2, t3 ... tn) 1 + 1 sql,网络也不成问题了 然后在内存里把老师再对应到每个学生上。 好吧 你是打算 用hibernate。 |
|
返回顶楼 | |