Когда вам нужно запросить документы с использованием SQL, в Couchbase есть две опции. Служба запросов и сервис Analytics . Наш блог, N1QL: запрашивать или анализировать?предоставляет подробный обзор обеих услуг. Я настоятельно рекомендую прочитать его до этого. Эта статья призвана расширить предыдущий блог, добавив несколько конкретных, практических примеров. Для каждого примера мы рассмотрим, как написать запрос в обеих службах, и рассмотрим различия в производительности. Цель состоит в том, чтобы читатели ушли с большим количеством знаний, чтобы помочь быстро идентифицировать образцы и варианты использования, которые лучше всего соответствуют каждой услуге.
Резюме
Прежде чем прыгать в примеры. Давайте освежимся на основных характеристиках двух сервисов.
Сервис запросов |
Аналитическая служба |
Используется для манипулирования данными в логике приложения. | Используется для отчетов, анализа (исторического, интерактивного) и информационных панелей. |
Наиболее эффективен для коротких оперативных запросов, которые извлекают или обрабатывают меньшие объемы данных. | Наиболее эффективен для более длинных, сложных специальных запросов, которые обычно извлекают и обрабатывают большие объемы данных. |
Поддерживает операции SELECT, INSERT, UPDATE, DELETE, MERGE. | Поддерживает только операции SELECT. |
См. Https://dzone.com/articles/n1ql-to-query-or-to-analyze для полной таблицы.
Настроить
В этом руководстве мы будем использовать Couchbase 6.5 и примеры данных, представленные в пользовательском интерфейсе администратора Couchbase. Моя среда — это 3-узловый кластер Couchbase 6.5 с 1536 МБ, выделенным для службы аналитики. Все остальные настройки являются настройками по умолчанию. Если у вас нет доступа к кластеру, вы можете быстро запустить Couchbase 6.5 в контейнере Docker, выполнив следующую команду:
docker run -d --name db -p 8091-8096:8091-8096 -p 11210-11211:11210-11211 couchbase:enterprise-6.5.0
Если вы идете по маршруту Docker, перейдите по адресу http: // localhost: 8091 в браузере после запуска контейнера и настройте экземпляр Couchbase, используя параметры по умолчанию на каждом шаге. Неважно, какое имя вы дадите своему экземпляру Couchbase.
Отказ от ответственности за исполнение
Мы рассмотрим время отклика для следующих примеров. Важно отметить, что ваша производительность может сильно различаться в зависимости от настроек среды Couchbase. Однако вы все равно сможете наблюдать аналогичные различия между службами Query и Analytics независимо от вашей среды.
Установить образец ковша для путешествий
На панели администратора Couchbase перейдите в «Настройки» -> «Образцы». Установите ковш с образцом путешествия. Подробную документацию о том, как это сделать, можно найти на нашем сайте документации .
Настройка службы запросов
Установка Sample Bucket также создает необходимые индексы. Это означает, что никакая дополнительная настройка не требуется для службы запросов.
Настройка службы аналитики
Для Службы аналитики нам нужно заполнить наборы данных для каждого «типа» документа в нашей корзине. Перейдите в Analytics Workbench и выполните следующие запросы для создания наборов данных:
SQL
1
CREATE DATASET routes ON `travel-sample` WHERE `type` = "route";
2
CREATE DATASET landmarks ON `travel-sample` WHERE `type` = "landmark";
3
CREATE DATASET hotels ON `travel-sample` WHERE `type` = "hotel";
4
CREATE DATASET airlines ON `travel-sample` WHERE `type` = "airline";
5
CREATE DATASET airports ON `travel-sample` WHERE `type` = "airport";
6
CONNECT LINK Local;
Это создаст наборы данных для маршрутов, ориентиров, отелей, авиакомпаний и аэропортов, используя набор образцов путешествий. Наконец, выполнение оператора CONNECT начнет заполнять каждый из наборов данных.
В следующих примерах мы будем использовать простые запросы N1QL. Подробное описание различий в языке N1QL между Query и Analytics см. На справочной странице N1QL для аналитики и N1QL для запроса в наших документах.
Вариант использования: получить все маршруты от LAX до SFO
Теперь мы готовы написать наш первый запрос. Для этого варианта использования мы хотим найти все доступные маршруты для данного аэропорта источника и назначения.
Какой сервис лучше?
Это, безусловно, операционный запрос, который вернет ограниченный объем данных. Это простой запрос, который не выполняет никаких агрегаций или сложных функций над нашими данными. Там только простой фильтр на источник и пункт назначения. Поэтому Query Service — очевидный выбор.
SQL
xxxxxxxxxx
1
select * from `travel-sample`
2
where type = "route"
3
and sourceairport = "LAX"
4
and destinationairport = "SFO"
Производительность: 4 миллисекунды
Это простой запрос, и он также возвращает только 7 документов. Это типичный рабочий запрос, который приложение может отправить в Couchbase. Производительность надежна и стабильна.
Аналитика Сервис Эквивалент
Давайте создадим один и тот же запрос для Службы аналитики для демонстрации. Служба Google Analytics слишком проста для такого простого запроса, как этот. Поэтому, если бы мы создавали приложение для этого варианта использования, мы бы не выбрали сервис Google Analytics. Мы ожидаем, что это будет хуже, чем служба запросов.
SQL
xxxxxxxxxx
1
select * from routes
2
where sourceairport = "LAX"
3
and destinationairport = "SFO"
Производительность: ~ 36 миллисекунд
Как вы можете видеть из этого примера. Служба запросов работает лучше всего для этого варианта использования, как и ожидалось. При большой нагрузке мы ожидаем, что служба запросов будет работать даже лучше, чем разница в 30 с лишним миллисекунд, чем показывает этот простой тест.
Вариант использования: получить города с большинством отелей
Какой сервис лучше?
Для этого варианта использования мы хотим выяснить количество отелей, доступных в каждом городе, и отсортировать результаты по городам с наибольшим количеством отелей. Это потребует от нас сканирования всех наших отелей и сбора данных по странам и городам, а затем их сортировки. Следуя логике, изложенной нами в начале, служба Google Analytics должна работать лучше для этого варианта использования. Давайте проверим эту теорию.
SQL
xxxxxxxxxx
1
select
2
country,
3
city,
4
count(id)
5
from hotels
6
group by country, city
7
order by count(id) desc
Производительность: ~ 36 миллисекунд
Интересно, что производительность этого запроса почти такая же, как в нашем предыдущем примере Google Analytics (36 мс), хотя предыдущий запрос был намного проще и меньше в вычислительном отношении. Это говорит о том, что базовая производительность в моей среде из трех узлов может составлять около 36 миллисекунд для запросов Google Analytics. Несмотря на то, что этот запрос является более сложным, чем наш первый пример, он все еще относительно прост для службы аналитики.
Эквивалент Query Service
Давайте создадим тот же запрос для службы запросов. Теоретически это более тяжелый запрос, чем в нашем предыдущем примере. Он также обрабатывает и возвращает намного больше данных, чем в первом примере. Мы ожидаем, что служба запросов не будет работать так же хорошо, как служба аналитики.
SQL
xxxxxxxxxx
1
select
2
country,
3
city,
4
count(id)
5
from `travel-sample`
6
where type = "hotel"
7
group by country, city
8
order by count(id) desc
Производительность: ~ 90 миллисекунд
Здесь у нас действительно большое расхождение в производительности. Как и ожидалось, служба аналитики может обрабатывать запрос в среднем в 2 раза быстрее, чем служба запросов.
Вариант использования: получить авиакомпании с большинством маршрутов
Какой сервис лучше?
Этот запрос задает вопрос, аналогичный нашему предыдущему примеру. Но поворот здесь заключается в том, что нам понадобится объединение, поскольку данные Авиакомпании находятся в отдельном типе документа в нашем ведре из данных маршрутов. Мы ожидаем, что служба аналитики будет работать лучше с этим запросом, потому что она выполняет агрегирование и соединение.
SQL
xxxxxxxxxx
1
select a.id,
2
a.callsign,
3
a.name,
4
a.country,
5
count(r.id) as route_count
6
from airlines a
7
join routes r on CONCAT("airline_", to_string(a.id)) = r.airlineid
8
group by a.id, a.callsign, a.name, a.country
9
order by route_count desc
10
limit 100
Производительность: 82 миллисекунды
Здесь мы видим, что этот запрос на самом деле начинает немного толкать сервис Google Analytics. Наш первый запрос Google Analytics занял в среднем 36 миллисекунд, а этот запрос увеличивает его до 82 миллисекунд. Основным отличием этого запроса является добавление JOIN.
Эквивалент Query Service
Помните, что в начале мы создали отдельные наборы данных Google Analytics для каждого типа документа в данных образца поездки. Каждый набор данных функционирует как его собственная таблица. Поэтому объединить их в запросе просто, если вы когда-либо ранее писали о SQL-соединениях. Служба запросов не имеет понятия «наборы данных» так же, как служба аналитики. Поэтому мы должны написать запрос немного по-другому, чтобы учесть все данные, находящиеся в одном сегменте. Нам нужно присоединить документы типа = «авиакомпания» к документам типа = «маршрут». Нам нужен подзапрос, чтобы сделать это.
SQL
xxxxxxxxxx
1
select a.id,
2
a.callsign,
3
a.name,
4
a.country,
5
count(r.id) as route_count
6
from `travel-sample` a
7
join (select id, airlineid from `travel-sample` where type = "route") r on CONCAT("airline_", to_string(a.id)) = r.airlineid
8
where a.type = "airline"
9
group by a.id, a.callsign, a.name, a.country
10
order by route_count desc
11
limit 100
Производительность: 2 секунды
Производительность службы аналитики в этом случае значительно выше благодаря использованию JOIN. Еще одним дополнительным преимуществом службы аналитики для этого случая является то, что написание JOIN проще, поскольку нам не нужно было создавать подзапрос для соединения.
Вариант использования: получить процентный рейтинг авиакомпаний с наибольшим количеством маршрутов
Какой сервис лучше?
Этот пример основывается на предыдущем, добавляя процентильный ранг количества маршрутов. Мы ожидаем, что производительность с Analytics будет выше, поскольку мы добавляем еще больше сложности и вычислений в запрос. Давайте посмотрим, какое влияние окажет добавление функции Window к нашему запросу.
SQL
xxxxxxxxxx
1
select
2
a.id,
3
a.callsign,
4
a.name,
5
a.country,
6
count(r.id) as route_count,
7
PERCENT_RANK() OVER (
8
ORDER BY count(r.id)
9
) AS `rank`
10
from airlines a
11
join routes r on CONCAT("airline_", to_string(a.id)) = r.airlineid
12
group by a.id, a.callsign, a.name, a.country
13
order by route_count desc
14
limit 100
Производительность: 85 миллисекунд
Добавление функции Window не было проблемой для службы аналитики, поскольку мы едва видим разницу в производительности.
Эквивалент Query Service
SQL
xxxxxxxxxx
1
select
2
a.id,
3
a.callsign,
4
a.name,
5
a.country,
6
count(r.id) as route_count,
7
PERCENT_RANK() OVER ( ORDER BY count(r.id) ) AS `rank`
8
from `travel-sample` a
9
join (select id, airlineid from `travel-sample` where type = "route") r on CONCAT("airline_", to_string(a.id)) = r.airlineid
10
where a.type = 'airline'
11
group by a.id, a.callsign, a.name, a.country order by route_count desc
12
limit 100
Производительность: 2 секунды
Когда мы добавляем функцию Window к нашему запросу службы запросов, мы также не можем обнаружить снижение производительности. Основным выводом, который мы можем сделать из этих результатов, является то, что JOIN является самым большим фактором производительности, а агрегация (в данном случае COUNT) является второй по величине.
Заключение
Мы надеемся, что эта статья помогла вам лучше понять две опции SQL в Couchbase и когда их применять. Обязательно ознакомьтесь со следующими ресурсами по Query and Analytics.
- Блог: N1QL : запрашивать или анализировать?
- Справочник по языку: N1QL для аналитики против N1QL для запроса
- Документация: Аналитика Введение
- Документация: основы запросов