Как эффективно выполнять массовый поиск индекса? - PullRequest
2 голосов
/ 16 июня 2010

У меня есть следующие виды сущностей:

  • Молекула
  • Атом
  • 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, и помните, что для меня не менее важно выполнить поиск в направлениях молекула -> атом и атом -> молекула. ​​

  • Кэширование?Я попытался использовать memcaching списки идентификаторов атомов с ключами идентификаторов молекул, но у меня есть тонны атомов и молекул, и кэш не может вместить его.

  • Как насчет денормализации данных путем созданияновый вид сущности, имя ключа которого является идентификатором молекулы, а значение которого представляет собой список идентификаторов атомов?Идея состоит в том, что вызов db.get на 500 клавишах, вероятно, быстрее, чем цикл 500 выборок с фильтрами, верно?

1 Ответ

3 голосов
/ 16 июня 2010

Ваш третий подход (денормализация данных), вообще говоря, правильный.В частности, db.get по ключам действительно примерно так же быстро, как получает хранилище данных.

Конечно, вам также нужно денормализовать и наоборот (сущность с идентификатором атома имени ключа, значение спискаидентификаторы молекул), и вам нужно будет тщательно обновлять все, когда атомы или молекулы изменяются, добавляются или удаляются - если вам нужно, чтобы это было транзакционным (несколько таких модификаций могут быть в игре одновременно), вам нужно организовать отношения предков.но я не вижу, как это сделать для обеих молекул и атомов одновременно, так что, возможно, это может быть проблемой.Возможно, если изменения достаточно редки (и в зависимости от других аспектов вашего приложения), вы можете сериализовать изменения в задачах в очереди.

...