益体网高性能电子商务Web应用 - O/R映射

1缓存

缓存是有很多层次的,有web server前端缓存,有动态页面静态化,有页面片断缓存,有查询缓存,也有对象缓存。不同层面的缓存适用于不同的应用场景。

 

针对OLTP类型的web应用,只要代码写的质量没有问题,最终的性能瓶颈毫无疑问还是数据库查询。应用服务器层面可以水平扩展,但是数据库是单点的,很难水平扩展,所以如何有效降低数据库查询频率,减轻数据库压力,是web应用性能问题的根源。

 

以上所有的缓存方式都可以直接或者间接的降低数据库访问,但缓存是有应用场景的,虽然新闻网站非常适合使用动态页面静态化技术,但是例如电子商务网站就不适合动态页面静态化,而页面缓存和查询缓存可以使用的场景也不多。但是对象缓存是所有缓存技术当中适用场景最广泛的,任何OLTP应用,即使实时性要求很高,你也可以使用对象缓存,而且好的ORM实现,对象缓存是完全透明的,不需要你的程序代码进行硬编码。

 

用不用对象缓存,怎么用对象缓存,是应用的架构问题。

 

也许你偏爱SQL,数据库设计当中大表有很多冗余字段,会尽量消除大表之间的关联关系,最终用户量和访问量很高以后,你会选择使用Oracle,雇佣资深的DBA,进行数据库调优和SQL调优,这是大多数公司走的路。

2 O/R映射

2.1对象缓存

也可以选择ORM(Hibernate/iBatis等),数据库设计当中避免出现大表,比较多的表关联关系,通过ORM以对象化方式操作。当用户量和访问量很高时,除了数据库端本身的优化,你还有对象缓存这条途径。例:

 

论坛的列表页面,需要显示topic的分页列表,topic作者的名字,topic最后回复帖子的作者,准备怎么做?

 

SQL代码:

select ... from topic left join user left join post .....; /*3张大表*/

 

需要通过join user表来取得topic作者的名字,然后需要join post表取得最后回复的帖子,postjoin user表取得最后回贴作者名字。

 

也许你说,可以设计表冗余,在topic里面增加username,在post里面增加username,所以通过大表冗余字段,消除了复杂的表关联:

 

SQL代码:

select ... from topic left join post...;

 

且不说冗余字段的维护问题,现在仍然是两张大表的关联查询。然后让我们看看ORM怎么做?

2.2 O/R映射

SQL代码:

select * from topic where ...; --分页条件,取Nid

 

就这么一条SQL搞定,比上面的关联查询对数据库的压力小多了。

 

也许你说,不对阿,作者信息呢?回贴作者信息呢?这些难道不会发送SQL吗?如果发送SQL,这不就是"N+1条问题"吗?

 

最坏情况下,有很多条SQL

select * from user where id = topic_id...; -- 作者

select * from post where id = last_topic_id...; -- 回帖

select * from user where id = post_id...; -- 回帖者

....

select * from user where id = topic_id...; -- 作者

select * from post where id = last_topic_id...; -- 回帖

select * from user where id = post_id...; -- 回帖者

.... N次...

 

何止N+1,根本就是3N+1SQL了。怎么说ORM性能高呢?

 

因为对象缓存在起作用,你可以观察到后面的3NSQL语句全部都是基于主键的单表查询,这3N条语句在理想状况下(比较繁忙的web网站),都可命中缓存。所以事实上只有一条SQL,就是:select * from topic where ...--分页条件

 

这条单表的条件查询和通过字段冗余简化过后的大表关联查询相比,当数据量大到一定程度以后(十几万条),查询的速度会差至少一个数量级,而且对数据库的压力很小,这就是对象缓存的真正威力!

 

更进一步分析,使用ORM,我们不考虑缓存的情况,那么就是3N+1SQL。但是这3n+1SQL的执行速度一定比大表关联查询慢吗?不一定!因为使用ORM的情况下,第一条SQL是单表的条件查询,在有索引的情况下,速度很快,后面的3nSQL都是单表的主键查询,在繁忙的数据库系统当中,3NSQL几乎可以全部命中数据库的data buffer。但是使用大表关联查询,很可能会造成全表扫描,性能是非常差的。

3结论

即使不使用对象缓存,ORMN+1SQL性能仍然很有可能超过大表关联查询,而且对数据库造成的压力要小很多。这个结论似难以置信,但是事实。前提是数据量和访问量都要比较大。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值