2015-10-16 6 views
1

я решил реализовать следующую стратегию ID для моих документов, который сочетает в себе документ «тип» с ID:DocumentDB Индекс производительности/фрагментация

doc.id = "docType_" + Guid.NewGuid().ToString("n"); 

// create document in collection 

Это приводит к идентификаторам, такие как следующие для моих документов :

usr_19d17037ea7f41a9b20db1a90f71d30d
usr_89fe82c93b264076aa1b6e1fb4813aaf
usr_2aa58c1c970a4c5eaa206a755c1c7bf4
msg_ec43510732ae47a6a5d5f323b7461d68
msg_3b03ceeb7e06490d998c3e368b435851

С помощью политики RangeIndex на идентификаторе я должен иметь возможность запрашивать коллекцию для определенных типов. Например:

SELECT * FROM c WHERE STARTSWITH(c.id, 'usr_') AND ... 

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

Моей главной задачей здесь является использование случайной строки GUID в ID. Я знаю, что в SQL Server у меня были проблемы с производительностью индекса и фрагментацией при использовании случайных GUID на первичном ключе в кластерном индексе.

Есть ли здесь такая же проблема? Кажется, что в DocumentDB уход за индексами был отвлечен от вас. Может ли последовательный идентификатор быть более идеальным/исполненным каким-либо образом?

ответ

3

tl; dr: Используйте отдельные поля для типа и идентификатор только для GUID и используйте индексы хэша для обоих.

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

ДокументDB предполагает использование GUID, а хэш-индекс (в отличие от индекса диапазона) идеально подходит для поиска одного соответствующего объекта по GUID. С другой стороны, если вы хотите найти набор документов, посмотрев на начало строки, я подозреваю, что, вероятно, будет более эффективным с индексом диапазона. Это предполагает, что STARTSWITH оптимизируется только при использовании индексов диапазона, но я не знаю, что он оптимизирован, даже если у вас есть индекс диапазона.

Моей рекомендацией было бы использовать отдельные поля для типа и идентификатор только для GUID и использовать индексы хэша для обоих. Это дает вам преимущество в том, что вы уверены, что запросы, подобные тем, которые вы показываете, будут очень эффективными и что запросы, которые объединяют предложение типа с другими параметрами, также смогут использовать хотя бы один индекс. Обратите внимание, что хэш-индексы этого типа (скажем, 2x 3 байта = 6 байт/документ) очень эффективны в пространстве, поэтому не беспокойтесь о необходимости двух из них. Эти два комбината должны быть намного меньше одного индекса диапазона, который должен иметь достаточную точность для покрытия всей длины вашего типа + GUID.

Помимо обсуждений, связанных с производительностью и пространством, я вижу несколько других недостатков для объединения типа с GUID: 1) при попытке получить один документ (как для прямого использования, так и как часть иностранного ключевой поиск), имеющий отдельный идентификатор GUID и использование хеш-индекса будет быстрее и экономичнее, чем использование индекса диапазона в комбинированном поле; 2) Объединение типа с идентификатором значительно усложняет некоторые миграции, которые обычно необходимо выполнять позднее. Предположим, что вы решили, например, разбить своих пользователей на авторов и читателей. Пользователи являются иностранными ключами, указанными в других типах документов (автор сообщения в блоге, комментарий читателя и т. Д.).) по идентификатору пользователя. Если этот идентификатор включает этот тип, вам потребуется не только изменить пользовательские документы для выполнения миграции, но вам также необходимо будет найти и изменить каждый внешний ключ. Если два поля (GUID и тип) были разделены, тогда вам нужно будет только изменить пользовательские документы. Гибкое программное мастерство в значительной степени связано с принятием решений, которые обеспечивают гибкость в будущем.

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

+0

Спасибо за отличный ответ! Я пытался придумать, как не добавлять это дополнительное поле типа в мои приложения POCOs, но я думаю, это просто необходимо. Теперь это немного больше. Я думаю, что это просто мои знания SQL и NoSQL, которые немного смешались, заставляя меня попытаться придумать что-то новое. – kspearrin

+0

Рад помочь. Можете ли вы принять мой ответ? –

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