Используя API ignite C ++, я пытаюсь найти способ выполнить SqlFieldsQuery для выбора определенного поля, но хотел бы сделать это для набора ключей.
Один из способов сделать это, это сделать SqlFieldsQuery, как это,
SqlFieldsQuery("select field from Table where _key in (" + keys_string + ")")
где keys_string
это список ключей в виде строки, разделенной запятыми.
К сожалению, это занимает очень много времени по сравнению с просто cache.GetAll(keys)
для набора ключей, keys
,
Есть ли альтернативный, более быстрый способ получения определенного поля для набора ключей из кеша зажигания?
РЕДАКТИРОВАТЬ:
Прочитав ответы, я попытался изменить запрос на:
auto query = SqlFieldsQuery("select field from Table t join table(_key bigint = ?) i on t._key = i._key")
Затем я добавляю аргументы из моего набора ключей следующим образом:
for(const auto& key: keys) query.AddArgument(key);
но при выполнении запроса я получаю сообщение об ошибке:
Failed to bind parameter [idx=2, obj=159957, stmt=prep0: select field from Table t join table(_key bigint = ?) i on t._key = i._key {1: 159956}]
Понятно, что это не работает, потому что есть только одно «?».
Поэтому я попытался передать vector<int64_t>
из ключей, но я получил ошибку, которая в основном говорит, что std::vector<int64_t>
не специализировался на зажигании BinaryType
, Так что я сделал это, как определено Вот. При звонке, например,
writer.WriteInt64Array("data", data.data(), data.size())
Я дал полю произвольное название «данные». Это приводит к ошибке:
Failed to run map query remotely.
К сожалению, API C ++ не является ни хорошо документированным, ни полным, поэтому мне интересно, что я что-то упустил или API не позволяет передавать массив в качестве аргумента для SqlFieldsQuery
,
Запрос, который использует IN
предложение не всегда правильно использует индексы. Обходной путь для этого описан здесь: https://apacheignite.readme.io/docs/sql-performance-and-debugging#sql-performance-and-usability-considerations
Также, если у вас есть возможность GetAll
вместо этого и поиск по ключу напрямую, то вы должны использовать его. Это, вероятно, будет более эффективным в любом случае.
Запрос с оператором «IN» не всегда будет использовать индексы. В качестве обходного пути вы можете переписать запрос следующим образом:
select field from Table t join table(id bigint = ?) i on t.id = i.id
а затем вызвать его как:
new SqlFieldsQuery(
"select field from Table t join table(id bigint = ?) i on t.id = i.id")
.setArgs(new Object[]{ new Integer[] {2, 3, 4} }))