只是不要急于加载大数据集,也许?:) (TL;DR:这不是一个答案,而是一个罗嗦的方式说“没有一个简单的答案”:)) 简单问题的简单解决方案。默认的(幼稚的)急切加载策略有效地解决了相当小的关系的N+1问题,但如果你试图急切加载巨大的关系,你可能会(也会)自杀。 例如,如果您只获取1000个带有id的相册,(1到1000)、那么您的ORM将触发额外的急切加载查询,以查找in列表中可能包含1000个id的select * from <whatever> where album_id in (1,2,3,...,1000)这样的艺术家和流派。where ... in查询的性能可能不是最佳的,即使是在现代数据库中,其查询计划器像爱因斯坦一样聪明。在一定的数据规模下,即使是如此小的一批数据,这也会变得非常慢。如果您尝试立即加载 * Just everything*(如您的示例中所示)-几乎不适用于任何实际数据使用(除了最小的用例)。 所以, 1.一般情况下,最好避免加载“全部”,而是批量加载数据;
1条答案
按热度按时间h5qlskok1#
只是不要急于加载大数据集,也许?:)
(TL;DR:这不是一个答案,而是一个罗嗦的方式说“没有一个简单的答案”:))
简单问题的简单解决方案。默认的(幼稚的)急切加载策略有效地解决了相当小的关系的N+1问题,但如果你试图急切加载巨大的关系,你可能会(也会)自杀。
例如,如果您只获取1000个带有id的相册,(1到1000)、那么您的ORM将触发额外的急切加载查询,以查找
in
列表中可能包含1000个id的select * from <whatever> where album_id in (1,2,3,...,1000)
这样的艺术家和流派。where ... in
查询的性能可能不是最佳的,即使是在现代数据库中,其查询计划器像爱因斯坦一样聪明。在一定的数据规模下,即使是如此小的一批数据,这也会变得非常慢。如果您尝试立即加载 * Just everything*(如您的示例中所示)-几乎不适用于任何实际数据使用(除了最小的用例)。所以,
1.一般情况下,最好避免加载“全部”,而是批量加载数据;
EXPLAIN
是您最好的朋友-始终分析您的ORM触发的查询。即使是经过实战测试的生产级ORM也可能(并且将)不时产生次优查询;1.后者对于大型数据集尤其如此--在一定的规模下,您将别无选择,只能从优秀的ORM API迁移到较低级别的定制SQL查询(至少对于瓶颈);
1.在一定的规模,甚至自定义SQL将不再有帮助-该规模的问题需要在另一个层面上解决(数据重塑,缓存,分片,CQRS等等...)