У меня проблемы с пониманием того, как работает план запроса couchbase. Я использую SpringData с Couchbase 4.1 и предоставляю индивидуальную реализацию репозитория Couchbase. Внутри моей пользовательской реализации репозитория Couchbase у меня есть метод ниже:
String queryAsString = "SELECT MyDatabase.*, META().id as _ID, META().cas as _CAS FROM MyDatabase WHERE segmentId = $id AND _class = $class ORDER BY executionTime DESC LIMIT 1";
JsonObject params = JsonObject.create()
.put(CLASS_VARIABLE, MyClass.class.getCanonicalName())
.put(ID_VARIABLE, segmentId);
N1qlQuery query = N1qlQuery.parameterized(queryAsString, params);
List<MyClass> resultList = couchbaseTemplate.findByN1QL(query, SegmentMembers.class);
return resultList.isEmpty() ? null : resultList.get(0);
В результате Spring Data создает следующий объект json, представляющий запрос к Couchbase:
{
"$class":"path/MyClass",
"statement":"SELECT MyDatabase.*, META().id as _ID, META().cas as _CAS from MyDatabase where segmentId = $id AND _class = $class ORDER BY executionTime DESC LIMIT 1",
"id":"6592c16a-c8ae-4a74-bc17-7e18bf73b3f8"
}
И проблема с производительностью, когда я выполняю его через Java и N1QL Rest Api или через cbq consol. Для выполнения этого запроса в cbq я просто заменяю ссылку на параметры точными значениями.
После добавления предложения EXPLAIN перед оператором select я упомянул разные планы выполнения. Выполнение этого запроса как параметризованного запроса через Java Spring Data или N1QL Rest Api. Я уже упоминал, что запрос не использует индекс, который я создал именно для этого случая. Определение индекса можно найти ниже:
CREATE INDEX `testMembers` ON MyDatabase `m`(`_class`,`segmentId`,`executionTime`) WHERE (`_class` = "path/MyClass") USING GSI;
Итак, когда я выполняю запрос через консоль cbq, Couchbase использует мой idnex, и производительность запросов очень хорошая. Но когда я выполняю этот запрос через N1QL rest api или Java, я вижу, что этот запрос не использует мой индекс. Ниже вы можете найти часть плана выполнения, подтверждающую этот факт:
"~children": [
{
"#operator": "PrimaryScan",
"index": "#primary",
"keyspace": "CSM",
"namespace": "default",
"using": "gsi"
},
Итак, вопрос в том, что правильное и законное поведение оптимизатора запросов couchbase? Значит ли это, что план запроса не учитывает реальные значения параметров? И вводил ли я вручную значения в строку запроса или существовал ли другой способ использовать параметризованный запрос N1Ql с правильным выбором индекса?
ИЗМЕНИТЬ
Согласно ответу шаши радж, я добавляю параметр N1qlParams.build (). Adhoc (false) в параметризованный запрос N1QL. Это не решает мою проблему, потому что у меня все еще есть проблемы с производительностью с этим запросом. Более того, когда я печатаю запрос, я вижу, что он такой же, как я описал ранее. Итак, мой запрос все еще неправильно проанализирован и вызывает снижение производительности.