当前位置: 首页 > 面试题库 >

内存有效的内置SqlAlchemy迭代器/生成器?

吕博耘
2023-03-14
问题内容

我有一个〜10M记录的MySQL表,可以使用SqlAlchemy进行交互。我发现对这个表的大子集的查询将消耗过多的内存,即使我以为我使用的是内置生成器,它可以智能地获取数据集的一口大小的块:

for thing in session.query(Things):
    analyze(thing)

为了避免这种情况,我发现我必须构建自己的迭代器,该迭代器会分块地进行处理:

lastThingID = None
while True:
    things = query.filter(Thing.id < lastThingID).limit(querySize).all()
    if not rows or len(rows) == 0: 
        break
    for thing in things:
        lastThingID = row.id
        analyze(thing)

这是正常的还是关于SA内置发电机我缺少什么?

这个问题的答案似乎表明内存消耗是不希望的。


问题答案:

大多数DBAPI实现在获取行时都会完全缓冲行-因此通常,在SQLAlchemy ORM甚至没有保留一个结果之前,整个结果集就在内存中。

但是,有效的方法Query是在返回对象之前默认情况下完全加载给定的结果集。这里的基本原理涉及的查询不仅仅是简单的SELECT语句。例如,在连接到可能在一个结果集中多次返回相同对象标识的其他表中(与急切加载相同),完整的行集需要存储在内存中,以便可以返回正确的结果,否则返回集合。可能只是部分填充。

因此Query提供了通过更改此行为的选项yield_per()。此调用将导致Query批量生成行,并在其中指定批量大小。正如文档所述,这仅在您不进行任何急切加载集合的情况下才是合适的,因此基本上是您真的知道自己在做什么。同样,如果底层的DBAPI预缓冲行,则仍然会有内存开销,因此该方法的伸缩性仅比不使用它更好。

我很少用过yield_per();
相反,我使用了您上面建议的使用窗口函数的LIMIT方法的更好版本。LIMIT和OFFSET存在一个巨大的问题,即非常大的OFFSET值会导致查询变得越来越慢,因为N的OFFSET会使查询分页N行-
就像执行相同的查询而不是一次,每次查询50次行数越来越大。使用窗口函数方法,我预取了一组“窗口”值,这些值引用了我要选择的表的块。然后,我发出单独的SELECT语句,每个语句一次从这些窗口之一中提取。

窗口函数方法在Wiki上,我使用它非常成功。

另请注意:并非所有数据库都支持窗口功能。您需要Postgresql,Oracle或SQL Server。恕我直言,至少使用Postgresql绝对值得-
如果您使用的是关系数据库,则最好使用最佳数据库。



 类似资料:
  • 问题内容: Java是否具有内置方法来置换或随机混排数字或字符数组?类似于c ++中的Random Shuffle STL? 问题答案: 您可以使用 如果您有数字数组,则可以使用:-

  • 生成器迭代 手动迭代生成器,递归执行 AsyncTask::next,调用Generator::send方法将将yield值作为yield表达式结果。 yield表达式可能是一个异步调用,我们这里为之后把异步调用的结果作为yield表达式结果铺垫。 yield外侧括号在PHP5必须,PHP7不需要。 如, $ip = (yield async_dns_lookup(...) ); ^

  • 这篇内容挺多的,而且比内容不好理解。或许新手看完后,还会一脸懵逼,不过这是正常的,如果你看完后,是迷糊的,那么建议你继续学习后面的内容,等学完,再回来看几次。 注:这也是我第二次修改内容没有改过的章节。 目录

  • 我是spark的新手,有关于迭代器使用spark内存的问题。 在使用数据集的Foreach()或MapPartitions()(甚至直接调用RDD的iterator()函数时,spark是否需要先将整个分区加载到RAM中(假设分区在磁盘中),还是在我们继续迭代时可以延迟加载数据(意味着,spark可以只加载部分分区数据执行任务,并将中间结果保存到磁盘)

  • 本文向大家介绍Python迭代器与可迭代与生成器,包括了Python迭代器与可迭代与生成器的使用技巧和注意事项,需要的朋友参考一下 示例 一个迭代是一个对象,可以返回一个迭代器。具有状态且具有__iter__  方法并返回迭代器的任何对象都是可迭代的。也可能是没有状态的对象,该对象实现了__getitem__方法。-该方法可以获取索引(从零开始),并IndexError在索引不再有效时引发。 Py

  • 我想在查询生成器laravel中orderBy 因为我的是类型 所以当它排序的时候...结果远远不是我想要的... 我的剧本就像这样 我已经试过了 我如何铸造OrderBy查询生成器,以便我可以排序desc