2013-12-12 2 views
3

Я пытался точно узнать, как различные типы индексов влияют на количество операций записи, необходимых для каждого объекта. Я думал, что я это понял, но потом я нашел случай, который бросил меня на петлю.Похудеть __key__ индексы стоят дополнительных операций записи?

У меня есть пользовательский объект root с несколькими дочерними объектами GameSummary, которые имеют временную метку и кучу других полей статистики (думаю, имя игрока, оценка и т. Д.).

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

Использование индекса по умолчанию для свойства timestamp создает два индекса (восходящий и нисходящий), но мне нужен только один из этих индексов, так что другая запись - просто накладные расходы. Моя первая мысль состояла в том, чтобы установить свойство как «noindex» (Indexed = False в python), а затем добавить индекс убывания, который мне нужен в index.yaml. Это не работает, по-видимому, потому, что планировщик запросов в любом случае пытается использовать индекс по умолчанию и просто не возвращает никаких результатов.

Тогда мне пришло в голову, что если бы я использовал временную метку в качестве ключа сущности, которую я мог бы сортировать по __key__ (который не имеет индексов по умолчанию) и добавлять только те индексы, которые мне действительно нужны. Я бегу сервер Dev с --require_indexes, что вызвало мои запросы на провал (как и ожидалось), пока я не добавил эти два индекса:

- kind: GameSummary 
    ancestor: no 
    properties: 
    - name: __key__ 
    direction: desc 

- kind: GameSummary 
    ancestor: yes 
    properties: 
    - name: __key__ 
    direction: desc 

В этот момент я смотрел на Datastore просмотра в консоли администратора и заметил, что столбец Write Ops для моих GameSummaries был всего 2 (Entities and EntitiesByKind). Я ожидал увидеть счет 5 здесь (еще 1 для первого индекса и еще 2 для индекса предка). Однако, по словам сервера dev, кажется, что я получаю нисходящий индекс __key__ для записи бесплатно?

Является ли консоль администратора лживой для меня? Или я пропускаю некоторые причуды индексов на свойстве __key__?

Даже незнакомец, добавляя индексы с дополнительными свойствами, что-то на __key__ как эти:

- kind: GameSummary 
    ancestor: no 
    properties: 
    - name: Player 
    - name: Enemy 
    - name: __key__ 
    direction: desc 

- kind: GameSummary 
    ancestor: yes 
    properties: 
    - name: Player 
    - name: Enemy 
    - name: __key__ 
    direction: desc 

не увеличивает Write Ops для GameSummary лиц либо. Возможно, я мог бы увидеть, что какая-то магия происходит с простым случаем, но это делает все больше и больше похожим на ошибку в dev-сервере для меня.

+0

Я бы начал с вопроса, почему вы используете временную метку в качестве ключа? В (предположительно маловероятном) событии, что два объекта записываются с одинаковой временной меткой, вы, вероятно, получите ошибку от App Engine. Кроме того, '__key__' действительно индексируется автоматически, но только в порядке возрастания (в противном случае было бы довольно медленно получать по ID, который я предполагаю). – dlebech

+0

Поскольку объекты GameSummary имеют родительский элемент User, было бы хорошо, если бы несколько объектов имели одну и ту же метку времени, пока они не были от одного и того же пользователя. На практике один пользователь не должен одновременно играть в две игры, чтобы иметь возможность дублировать временные метки, поэтому я не беспокоюсь о конфликтах в этом случае. – chippydip

ответ

1

Просто подтвердил, что это ошибка sdk, вы должны сообщить об этом, если он не существует. Я тестировал его с помощью appstats на реальном сервере, и он добавляет дополнительную запись при добавлении индекса убывающего индекса.

Но как совет, так как я столкнулся с тем же, чтобы избежать нескольких индексов и всегда заказывать по времени в порядке убывания, вы можете выполнить операцию смены битов на метке времени и сохранить ее шестнадцатеричное + случайное число, чтобы избежать конфликтов , Он работал для меня без проблем. Хотя мое точное использование заключалось в том, что у меня действительно был собственный счетчик вместо timestamp, но по причинам проекта.

+0

Спасибо за тестирование на живых серверах. Я пошел дальше и создал новый [Issue] (http://code.google.com/p/googleappengine/issues/detail?id=10397) для ошибки, если кто-то еще находит этот вопрос и хочет его отслеживать. – chippydip

Смежные вопросы