Access denied, Please sign in and make sure you have proper permission.
Topic has been selected as the excellent topic by the admin.
和公司 DBA 经常提醒的基本吻合~有图有真相,看了源码和设计,忍不住想在自己的系统中试试~
文中说到n + 1 才能有效利用ORM缓存
,这个真是学习了
到了那个级别数据量,发现关系数据库就是当非关系数据库使的。
文章不错。写了 read-thru, write-thru, write-behind 三种
还有一个策略是提前计算好全部 cache,然后在读之前就更新过期 cache
这篇文章不错,学到了很多,就是没有这么大的数据量可以实践,不过随时可以在新项目中应用这个新思路。
想方设法高效利用内存来减少 IO 的读取。对 n + 1 查询增加上 id 与二级缓存
应用很醒脑啊
rails4 最大量缓存 就没有毕要 n+1 了,同意 n+1 的观点
吐槽无力,完全无力苟同 n+1 有利于缓存的观点。
@ bhuztez 我认为他说的 n+1 是指多进行单表主键查询
如果没有二级缓存的情况下 细查询粒度 数据库自身的查询缓存的利用率也会提高
#13 楼 @ jasl 基本上每个点都有值得怀疑的地方。就算大体按他这个思路,我们现在来看一下 n+1 那个点。
明明是可以 1+1 的,也不用拆成两张表的。所有 ID 都已知啊,直接一条 SELECT 不就完事了。1 条和 n 条对数据库没有本质区别。且 n 条多浪费 n-1 次 round trip。
一边说要省 I/O,拆表增加了 I/O 负担就不提了。特别是他这个例子里,拆跟没拆没啥区别的。
其实嘛,大谈数据库,还是要抠那么点性能的,连SELECT *
出现都不给理由的,这篇文章肯定是没用心写。吐槽真的很无力。
好吧,我还是来恶心他一句,从 2007 年到 2013 年,一点点长进都没有啊,我都不想为他捉急了
#16 楼 @ hooopo
反正你的理由不够有说服力。且此处不用SELECT *
显然不用拆表...
有能支持 N+1 不能证明没有能支持 1+1 的啊
#17 楼 @ bhuztez
从理论上讲,一个 web 系统可以做缓存优化的地方太多了。而你单揪着SELECT *
不放一点意思也没有,况且,那是个费力未必讨好的活儿。
pro tip:
If you really want to make a point about the performance of a particular thing, can you at least pretend you're using science?
N+1 为的是可以直接在 View 里面存取缓存,让缓存的颗粒度更小
#18 楼 @ hooopo SELECT *
是公认的 bad practise。只要你没理由,是不该用SELECT *
的。SELECT *
首先是让代码维护变得困难,其次是有性能损失。
难道在这里SELECT *
一点问题都没有吗?就是你用了该死的SELECT *
你才要拆表。
#24 楼 @ Rei 不要扯开去啊,就这个例子,把 blog contents 拆表,这拆跟没拆有什么区别么...
#25 楼 @ bhuztez 或者你手头有大数据可以测一测。决定数据库模式的不是我,当时领我的组长把那 9000 万数倒来倒去、拆来拆去,后来发现这样弄比较快,就这样做了。
我个人不喜欢因为性能问题拆表,应该按逻辑分,所以我不想再碰大数据了。
数据量上去之后,关系数据库的 join 查询都不能用,热数据要冗余,大部分是主键查询……经历那一次后,我更加坚定用 Mongodb 了。
#26 楼 @ Rei 我不是说不该为了性能原因拆表什么的。把拆表这个问题无限制扩大范围是得不出什么结论的,最多就是根据应用类型来决定,那就是一句废话。
我是说 robbin 这个例子拆跟不拆没什么区别,可能还是不拆好....这里根本就没给出任何理由。整篇下来基本就这么个思路。现在采用的这种方式比最烂的好很多了,所以这是一种很好的方式。
#28 楼 @ bhuztez 我也没测过 select col, col2
是不是跟拆分后的 select *
性能一样,按 robbin 的说法应该后面的好。这就留给有心人啦,我用 Mongodb。
再说一个,为什么要用 select *
呢,一条数据在不同的位置可能要调用不同的字段,全部取出来就可以缓存在内存,不同地方 select 不同的 col 缓存效率就低。当然也可以通过页面片段缓存,实际哪个好要看场合了。
#27 楼 @ Rei
首先是一句废话,用什么数据库取决于你的应用类型。
为什么要用 RDBMS,是因为数据本身之间存在关系啊。数据关系处理起来是很难的。要应用自己保证 ForeignKey Constraint 还是太麻烦了,所以才会出现各种 RDBMS。这也是为什么你总是要先 normalize 找出所有关系。
数据量上去之后,关系数据库的 join 查询都不能用
不是的。假如你知道你需要哪些 JOIN。Oracle 的 Table Cluster 可以把相关数据放在一起,这样即便是一个很大的 cluster,也是可以 JOIN 的。Google 开发的 F1 也是这么干的。
我更加坚定用 Mongodb 了
MongoDB 解决的完全不是同一类问题。你用 MongoDB,你对数据的假设是,对于任意一条记录,任何地点都可能对它发起写请求,且不存在某个地点发起写请求的次数特别多,此时你想要保证多数地点要可写。对,默认你已经跨地理分布的多个数据中心了。
#30 楼 @ Rei
不是只有select *
才能把所有字段取出来。
这里就是少取一个字段即可避免拆表
robbin 的这篇文章很赞,将 Rails 中各种 cache 的最佳实践都很详细地总结了一次,强烈推荐。
另外,我在微博上提到过:Rails 的 ActiveRecord 在 3.1 以后,对于 n+1 有更先进的处理,通过 Eager Loading http://t.cn/zYnMxad 会转化成 in 查询,变成 1+1,而且 in 查询可以通过 cache server 的 multiget 方式来批量命中。
fork 了那个 cache,正在看如何改进这个。
#31 楼 @ bhuztez 这里说的应用类型就是完整性要求不严格的 Web 应用,Startup 也买不起 Oracle,所以我也只说我的选择罢了。
我表示觉得 robbin 这篇文章很强大,同时盼望 @ bhuztez 写出同样强大文章,但具有不同的观点
#3 楼 @ ywjno n+1 有效使用缓存,记得几年前,robinfan 在 KongfuRails 里就讲过了