Механизм приложений: 13 StringPropertys против 1 StringListProperty (индексирование / хранение и производительность запросов в w.r.t.) - PullRequest
3 голосов
/ 03 августа 2009

Сначала немного истории: GeoModel - это библиотека, которую я написал, которая добавляет базовые функции геопространственной индексации и запросов к приложениям App Engine. Это похоже на подход к геохашированию. Эквивалентный хэш местоположения в GeoModel называется «геоэлемент».

В настоящее время библиотека GeoModel добавляет 13 свойств (location_geocell__n_, n = 1..13) для каждого объекта, учитывающего местоположение. Например, сущность может иметь значения свойств, такие как:

location_geocell_1 = 'a'
location_geocell_2 = 'a3'
location_geocell_3 = 'a3f'
...

Это необходимо для того, чтобы не использовать фильтр неравенства во время пространственных запросов.

Проблема подхода с 13 свойствами заключается в том, что для любого гео-запроса, который приложение хотело бы запустить, необходимо определить и построить 13 новых индексов. Это определенно хлопот в обслуживании, как я только что болезненно осознал, переписывая демонстрационное приложение для проекта. Это приводит к моему первому вопросу:

ВОПРОС 1: Существуют ли какие-либо существенные издержки хранения на индекс? то есть, если у меня есть 13 индексов с n сущностями в каждом, по сравнению с 1 индексом с 13n сущностями в нем, намного ли хуже первый с точки зрения хранения?

Похоже, что ответ на (1) - нет, согласно этой статье , но я просто хотел бы посмотреть, имел ли кто-либо другой опыт.

Теперь я рассматриваю настройку библиотеки GeoModel, чтобы вместо 13 строковых свойств был только один StringListProperty с именем location_geocells, то есть::1024*

location_geocells = ['a', 'a3', 'a3f']

В результате получается намного чище index.yaml. Но я ставлю под сомнение последствия для производительности:

ВОПРОС 2: Если я переключусь с 13 строковых свойств на 1 StringListProperty, это повлияет на производительность запроса; мой текущий фильтр выглядит так:

query.filter('location_geocell_%d =' % len(search_cell), search_cell)

и новый фильтр будет выглядеть так:

query.filter('location_geocells =', search_cell)

Обратите внимание, что первый запрос имеет пространство поиска _n_ сущностей, тогда как второй запрос имеет пространство поиска _13n_ сущностей.

Похоже, что ответ на вопрос (2) заключается в том, что оба результата приводят к одинаковой производительности запросов, за совет № 6 в этом сообщении в блоге , но, опять же, я хотел бы посмотреть, есть ли у кого-то отличающиеся опыт реального мира с этим.

Наконец, если у кого-то есть какие-либо другие предложения или советы, которые могут помочь улучшить использование хранилища, производительность запросов и / или простоту использования (в частности, w.r.t. index.yaml), пожалуйста, дайте мне знать! Источник можно найти здесь geomodel & geomodel.py

Ответы [ 3 ]

5 голосов
/ 03 августа 2009

Вы правы, что нет существенных накладных расходов для каждого индекса - 13n записей в одном индексе более или менее эквивалентно n записей в 13 индексах. Однако общий предел количества индексов составляет 100, поэтому это съедает значительную часть ваших доступных индексов.

Тем не менее, использование ListProperty, безусловно, является намного лучшим подходом с точки зрения удобства использования и потребления индекса. Как вы и предполагали, нет разницы в производительности между запросами небольшого индекса и гораздо большего индекса, если предположить, что оба запроса возвращают одинаковое количество строк.

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

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

1 голос
/ 03 августа 2009

Наконец, если у кого-то есть какие-либо другие предложения или советы, которые могут помочь улучшить использование хранилища, производительность запросов и / или простоту использования

StringListproperty - способ пойти по причинам, указанным выше, но при фактическом использовании можно добавить геоэлементы к тем, которые имеют ранее существующий StringList, чтобы можно было запрашивать несколько свойств.

Таким образом, если бы вы предоставили API более низкого уровня, он мог бы работать с реализациями полнотекстового поиска, такими как bill katz's

def point2StringList(Point, stub="blah"):
    .....
    return ["blah_1:a", "blah_2":"a3", "blah_3":"a3f" ....]

def boundingbox2Wheresnippet(Box, stringlist="words", stub="blah"):
    .....
    return "words='%s_3:a3f' AND words='%s_3:b4g' ..." %(stub)

etc.
0 голосов
/ 20 сентября 2011

Похоже, вы получили 13 индексов, потому что вы закодировали в шестнадцатеричном формате (для читабельности человека / уровней карты?). Если бы вы использовали полный потенциал байта (ByteString), у вас было бы 256 ячеек вместо 16 ячеек на символ (байт). Там за счет уменьшения гораздо меньшего количества индексов для одинаковой точности.

ByteString является просто подклассом str и индексируется аналогично, если его длина менее 500 байт.

Однако количество уровней может быть меньше; мне 4 или 5 уровней практически достаточно для большинства ситуаций на «Земле». Для более крупной планеты или при каталогизации каждой частицы песка, в любом случае, может потребоваться ввести больше делений независимо от используемого кодирования. В любом случае ByteString лучше, чем шестнадцатеричное кодирование. И помогает уменьшить индексирование существенно .

  • Для представления 4 миллиардов ячеек низкого (est) уровня все, что нам нужно, это 4 байта или просто 4 индекса . (Из базовой компьютерной арки или адресации памяти).
  • Для представления того же самого нам потребуется 16 шестнадцатеричные цифры или 16 индексов .

Я могу ошибаться. Может быть, число уровней индекса, соответствующих уровням масштабирования карты, является более важным. Пожалуйста, поправьте меня. Я планирую попробовать это вместо hex, если только один (другой) человек найдет это значимым:)

Или решение, которое имеет меньше больших ячеек (16), но больше (128,256) по мере продвижения по иерархии. Есть мысли?

например:

  • [0-15] [0-31] [0-63] [0-127] [0-255] дает ячейки низкого уровня 1G с 5 индексами с уменьшением размера log2.
  • [0-15] [0-63] [0-255] [0-255] [0-255] дает 16G ячейки низкого уровня с 5 индексами.
...