您如何有效地批量索引查找?

时间:2010-06-16 02:11:27

标签: python google-app-engine indexing scalability

我有这些实体种类:

  • 分子
  • 原子
  • MoleculeAtom

鉴于长度为数百的list(molecule_ids),我需要得到{molecule_id: list(atom_ids)}形式的词典。同样地,如果list(atom_ids)长度在饥饿中,我需要得到{atom_id: list(molecule_ids)}形式的词典。

这两个批量查找​​都需要非常快。现在我正在做类似的事情:

atom_ids_by_molecule_id = {}

for molecule_id in molecule_ids:
    moleculeatoms = MoleculeAtom.all().filter('molecule =', db.Key.from_path('molecule', molecule_id)).fetch(1000)
    atom_ids_by_molecule_id[molecule_id] = [
        MoleculeAtom.atom.get_value_for_datastore(ma).id() for ma in moleculeatoms
    ]

就像我说的,len(molecule_ids)是数百个。我需要在几乎每一个请求上都进行这种批量索引查找,我需要它快速,而且现在它太慢了。

思路:

  • 使用Molecule.atoms ListProperty做我需要的吗?考虑一下我在MoleculeAtom节点上存储其他数据,并记住它对于我在分子 - >原子和原子 - >分子方向上进行查找同样重要。

  • 缓存?我试过用分子ID键入的原子ID列表,但我有大量的原子和分子,缓存不适合它。

  • 如何通过创建一个新的实体类来对数据进行非规范化,该实体类的键名是分子ID,其值是原子ID列表?这个想法是,在500个密钥上调用db.get可能比使用过滤器循环500个抽取更快,对吗?

1 个答案:

答案 0 :(得分:3)

一般来说,你的第三种方法(非规范化数据)是正确的方法。特别是,按键db.get确实和数据存储区一样快。

当然,您还需要反过来反规范化(具有键名称原子ID的实体,值为分子ID列表)并且需要在更改,添加或删除原子或分子时仔细更新所有内容 - 如果你需要交易(多个这样的修改可能同时发挥作用)你需要安排祖先关系..但我不知道如何为分子和原子在同一时间,所以也许这可能是一个问题。也许,如果修改很少(并且取决于应用程序的其他方面),您可以序列化排队任务中的​​修改。