#google-app-engine #google-cloud-platform #google-cloud-datastore #query-optimization
#google-app-engine #google-облачная платформа #google-облако-хранилище данных #оптимизация запросов
Вопрос:
У меня есть два объекта в хранилище данных Google:
A:
id,
name,
.... a lot of other columns
B:
id,
Key(A, <id_of_A_record>) --> Reference Property A,
URL,
size
... and more columns
У меня есть куча идентификаторов, и я хочу запросить эти идентификаторы.
Теперь я могу добиться этого с помощью
A_ids = [1, 2, 3, 4, 5, 6]
B.all().filter('A IN', A_ids).fetch(None)
Однако, если имеется 6 идентификаторов A_id, существует 6 вызовов db, что превосходит цель IN . Могу ли я каким-либо образом добиться этого, избегая фильтра IN (слишком много вызовов DB)?
Спасибо!
Ответ №1:
На самом in
деле фильтр — это просто удобная функция, предоставляемая вашим ORM. За кулисами он выполняет ряд действий OR
, чтобы это произошло.
Имя фильтра в (value1, …, valueN) преобразуется в (name = value1) ИЛИ … ИЛИ (name = valueN) (также дизъюнкционный узел)
https://googleapis.dev/python/python-ndb/latest/query.html#google.cloud.ndb.query .FilterNode
Даже OR
s не поддерживаются самим хранилищем данных, оно просто эмулируется клиентской библиотекой:
Природа механизма индексных запросов накладывает определенные ограничения на то, что может делать запрос. Запросы в режиме хранилища данных не поддерживают совпадения подстрок, совпадения без учета регистра или так называемый полнотекстовый поиск. Операторы NOT, OR и != изначально не поддерживаются, но некоторые клиентские библиотеки могут добавить поддержку поверх режима хранилища данных.
https://cloud.google.com/datastore/docs/concepts/queries#restrictions_on_queries
Я думаю, что клиентская библиотека выполняет OR
s, запуская отдельные запросы, поэтому вы видите эти вызовы 6 db. Я не думаю, что вы сможете избежать этого без реструктуризации ваших данных.