如何使用SQLAlchemy和PostgreSQL有效地排序大表中的所有行?

时间:2017-08-30 20:55:09

标签: query-performance postgresql-performance python sqlalchemy

我正在构建一个推荐系统。我有下表存储每个项目的功能:

class Item_feature(db.Model):
    __tablename__ = "Item_feature"
    item_id = db.Column(db.Integer, primary_key=True)
    feature_id = db.Column(db.Integer, primary_key=True)
    weight = db.Column(db.Integer)

我不需要创建Item表,因为唯一重要的信息是他们的ID(除了功能)。这就解释了为什么item_id键不是外键。

每个项目都可以,比方说40个功能。因此,如果推荐者有200k项,那么就会有数百万行。我需要将项目保留在内存中,以避免在必须提出建议时获取它们。我没有找到更好的表示来存储这些功能,因此这方面的想法也非常有用。

初始化系统时,我需要获取所有项目的所有功能。如果项目没有按item_id排序(或者至少按item_id分组),我将不得不在功能列表上的每个循环上查找具有相同item_id的项目。

我在SQLAlchemy中使用此查询来获取功能:

features = model.Item_feature.query.all().order_by(model.Item_feature.item_id)

但这可能真的很慢。使用以下内容:

features = model.Item_feature.query.all()

不保证结果将被排序。它似乎取决于将数据添加到数据库中的顺序。

如果对功能进行分组或排序,我可以使用单个循环执行更高效的操作,例如:

item = None
item_id = None
for f in features:
    # Adds features to item until item_id changes
    if item_id != f.item_id: 
        item_id = f.item_id
        item = Item(item_id)
        self.items[item_id] = item # Adding new item to the dictionary of items
    item.new_feature()

如代码所示,我正在使用字典来存储项目。我不确定这是不是一个好的选择。

那么,考虑到可能的大量行,我怎么能以有效的方式获得第一个主键user_id分组(或排序)的行?

1 个答案:

答案 0 :(得分:1)

  

那么,考虑到可能的大量行,我怎么能以有效的方式获得第一个主键user_id分组(或排序)的行?

为了存储机器学习权重,我尝试了#No; NoSQL解决方案" (在PostgreSQL或文件甚至上),因为连续处理数百万个权重是不切实际的。

这个想法是,当ML完成训练/再训练时,将你的权重存储在你需要阅读它们以在app中使用的相同格式(结构,顺序,分组等)中做出预测/建议。

这将将数据重组成为一次性写入的培训阶段的成本摊销,并避免在“"系统初始化”时重构数据。就像你说的那样。

PostgreSQL的JSONB字段可以容纳1GB的数据。您可以保留字典和列表,这样您就可以保留使用Python代码段计算的结构。

或者,如果您还希望避免将权重反序列化为模型使用的格式,则可以将其存储为binary blob

否则,将相同格式的权重存储在文件上也是有效的。