n1ql производительность первичного сканирования - PullRequest
0 голосов
/ 26 ноября 2018

Мой документ выглядит следующим образом:

{
  "date": "1970-02-19",
  “uid”: 2345
  “profile": [
    "Profile Text, Profile Text, Profile Text, Profile Text, Profile Text",
    "Profile Text,  Profile Text,  Profile Text,  Profile Text,  Profile Text",
    "Profile Text,  Profile Text,  Profile Text,  Profile Text,  Profile Text"
  ],
  “channel_a”: {
    "reach": 915157,
     "likes": 6.39,
     "shares": 8.15,
     "followergrowth": 6.89
  },
  “channel_b”: {
    "reach": 894888,
    "response": 8.64,
    "influence": 7.03,
    "reject": 5.09
  },
  “channel_c” {
    "reach": 396938
  }
}

Ключ документа состоит из типа документа, идентификатора пользователя (число) и даты.например, каналы: 9999: 2015-12-31.Я хочу создать запрос, чтобы получить список из 10 лучших пользователей, которые имеют самый высокий уровень вовлеченности для определенного канала в данный календарный месяц.Критерии могут различаться в зависимости от канала и требований.

В приведенном выше плане запроса используется сканирование основного индекса, выполнение которого заняло почти минуту.Квалифицированный набор данных составляет около 1,3 тыс. Строк, но это может увеличиться до 5 тыс. Строк.Есть ли какой-нибудь механизм на Couchbase, который я могу использовать для повышения производительности?Кроме того, я ищу масштабируемое решение по мере увеличения размера данных.

select 
    s. uid,
    sum(s.channel_c.reach) channel_c_Reach,
    sum(s.channel_b.reach) channel_b_Reach,
    sum(s.channel_a.likes) channel_a_Likes
FROM channels s
where meta().id like ‘channels:%:2016-05-%’
group by s.uid
ORDER BY sum(s.channel_a.likes) DESC
LIMIT 10 

Ответы [ 3 ]

0 голосов
/ 26 ноября 2018
CREATE INDEX ix1 ON channels(uid, date, channel_a.likes, channel_c.reach, channel_b.reach)
WHERE meta().id like "channels:%";
SELECT
    s.uid,
    sum(s.channel_c.reach) channel_c_Reach,
    sum(s.channel_b.reach) channel_b_Reach,
    sum(s.channel_a.likes) channel_a_Likes
FROM channels s
WHERE meta(s).id like "channels:%" AND s.uid IS NOT NULL AND s.date LIKE "2016-05-%"
group by s.uid
ORDER BY sum(s.channel_a.likes) DESC
LIMIT 10 ;

Также Оформить заказ https://blog.couchbase.com/understanding-index-grouping-aggregation-couchbase-n1ql-query/

0 голосов
/ 27 ноября 2018

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

  1. Фильтр [например, «каналы:%: 2015-05-%»] будет принудительно сканировать весь индекс для генерации групп, а затем извлекать данные для агрегации.Это, вероятно, где большая часть времени проводится, поэтому решение этой проблемы является ключевым.Есть ли у вас возможность изменить ключ документа, чтобы повысить селективность, то есть, поместив компонент «дата» перед «идентификатором пользователя»?Он должен работать намного быстрее, если вы можете изменить его на [например: channel: 2016-05-% ']
  2. Если вы используете Couchbase v6.0, вы можете включить службу Couchbase Analytics в ваших настройках.https://docs.couchbase.com/server/6.0/analytics/primer-beer.html. Couchbase Analytics использует SQL ++ , иначе.N1QL для Couchbase Analytics.Это означает, что вы можете использовать тот же запрос и направить его в службу аналитики.Он предназначен для работы с запросами, которым требуется доступ к большому количеству документов, с использованием алгоритмов параллельной обработки.

Вариант 1 будет наиболее эффективным способом решения этой проблемы, а SQL ++ CouchbaseАналитика должна дать вам значительное улучшение без каких-либо изменений.

0 голосов
/ 26 ноября 2018

Если ваш запрос использует первичный индекс, вы можете многое улучшить.Главное - создать несколько индексов для поддержки вашего запроса.

Ознакомьтесь с этой статьей, в которой рассказывается о том, как создавать индексы для групп: https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/groupby-aggregate-performance.html

...