Движок приложений:13 StringPropertys против1 Свойство StringListProperty (w.r.t.индексация / хранение и производительность запросов)

StackOverflow https://stackoverflow.com/questions/1220794

Вопрос

Сначала немного предыстории: Геомодель это библиотека, которую я написал, которая добавляет очень простые функции геопространственного индексирования и запросов к приложениям 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, т.е.:

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.py

Это было полезно?

Решение

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

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

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

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

Другие советы

  
    

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

  

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

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

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.

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

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

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

  • Для представления 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] дает 16 г низкоуровневых ячеек с 5 индексами.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top