2010-06-16 58 views
2

我有这些实体类:如何有效地批量索引查找?

  • 分子
  • 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.atomsListProperty做什么,我需要什么?考虑到我在MoleculeAtom节点上存储了额外的数据,请记住,对于我在分子 - >原子和原子 - >分子方向进行查找同样重要。

  • 缓存?我尝试了由分子ID键入的原子ID的memcaching列表,但我拥有大量的原子和分子,而缓存无法适应它。

  • 如何通过创建一个新的实体类型来反规范化数据,其键名是一个分子ID,其值是一个原子ID列表?这个想法是,在500个键上调用db.get可能比通过500次过滤循环更快,对吧?

+0

这听起来很像使用数据库(使用非规格化数据)最好的问题。因为它可以更好地扩展并且数据库固有地被设计为以最有效的方式处理像这样的数据集连接。 – 2010-06-17 01:36:47

回答

3

第三种方法(反规格化数据)一般来说是正确的。特别是,按键的db.get确实与数据存储的速度一样快。当原子或分子被改变,添加或更改时,您需要反方向去归一化(具有键名称原子ID的实体,值分子ID列表),并且需要仔细更新所有内容。删除 - 如果你需要这是事务性的(多个这样的修改可能在同一时间发挥作用),你需要安排祖先关系..但我不知道如何做这两个分子原子在同时,也许这可能是一个问题。也许,如果修改很少(并且取决于应用程序的其他方面),则可以对排队任务中的​​修改进行序列化。