代码之家  ›  专栏  ›  技术社区  ›  Liron Shapira

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

  •  2
  • Liron Shapira  · 技术社区  · 16 年前

    我有以下几种实体:

    • 分子
    • 原子
    • 分子原子

    给予 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节点上存储额外的数据,记住在molecule中进行查找对我来说同样重要->原子和原子->分子方向。

    • 缓存?我尝试了memcaching由molecule ID键控的原子ID列表,但是我有大量的原子和分子,而缓存不能满足它。

    • db.get 在500个键上可能比用过滤器循环500个回迁要快,对吧?

    1 回复  |  直到 16 年前
        1
  •  3
  •   Alex Martelli    16 年前

    一般来说,您的第三种方法(数据非规范化)是正确的。特别地, db.get 按键访问的速度确实与数据存储的速度差不多。

    当然,你也需要用另一种方法去规范化(实体的键名是atom ID,值是分子ID的列表),并且当原子或分子被改变,添加,或者删除——如果您需要它是事务性的(多个这样的修改可能同时进行),那么您需要安排祖先关系。。但我不知道如何对这两种分子都这么做 原子同时存在,所以这可能是个问题。也许,如果修改足够少(并且取决于应用程序的其他方面),您可以在队列任务中序列化修改。