我有这些实体类型:
- 分子
- 原子
- 分子原子
给定一个长度为数百的 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 次获取更快,对吗?
最佳答案
一般来说,您的第三种方法(对数据进行非规范化)是正确的。特别是,按键的 db.get
确实与数据存储区的获取速度一样快。
当然,您也需要反规范化(具有键名称原子 ID 的实体,值分子 ID 列表),并且需要在更改、添加或删除原子或分子时仔细更新所有内容- 如果你需要它是事务性的(多个此类修改可能同时发挥作用),你需要安排祖先关系..但我不知道如何为分子和 同时存在原子,所以这可能是一个问题。也许,如果修改足够罕见(并且取决于应用程序的其他方面),您可以在排队任务中序列化修改。
关于python - 如何有效地进行批量索引查找?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3050304/