Jena/Arq: обработка запросов застревает
Если есть проблема со следующим SPARQL-запросом:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX :<http://www.test.at/DA.owl#>
SELECT ?ModuleName ?SLAName ?SLOName ?SLOTypeName ?SLOTHV (AVG(DISTINCT ?SLTTV) AS ?AVGTrackValue) (COUNT(DISTINCT ?SLT) AS ?SLTCOUNT)
WHERE {
?Module rdf:type :ServiceModule .
?SLA rdf:type :ServiceLevelAgreement.
?SLO rdf:type :ServiceLevelObjective .
?SLT rdf:type :ServiceLevelTracking .
?Day rdf:type :Day .
?Holiday rdf:type :Holiday .
?rel1 rdf:type :RelationFact .
?rel2 rdf:type :RelationFact .
?rel3 rdf:type :RelationFact .
?rel4 rdf:type :RelationFact .
?rel5 rdf:type :RelationFact .
?Module :hasName ?ModuleName .
?SLA :hasName ?SLAName .
?SLO :hasName ?SLOName .
?SLO :hasType ?SLOType .
?SLO :hasThresholdValue ?SLOTHV .
?SLOType :hasName ?SLOTypeName .
?SLT :hasDayName ?SLTDayName .
?SLT :hasType ?SLTType .
?SLT :hasTrackedDateTime ?trackTime .
?SLT :hasTrackedValue ?SLTTV .
?Day :hasDayName ?DayName .
?Holiday :hasDate ?HolidayDate .
?Holiday :hasStartTime ?HolidayStartTime .
?Holiday :hasEndTime ?HolidayEndTime .
?rel1 :hasParent ?Module .
?rel1 :hasChild ?SLA .
?rel2 :hasParent ?Module.
?rel2 :hasChild ?SLT .
?rel3 :hasParent ?SLA .
?rel3 :hasChild ?SLO .
?rel4 :hasParent ?SLA .
?rel4 :hasChild ?Day .
?rel5 :hasParent ?SLA .
?rel5 :hasChild ?Holiday .
Filter(regex(str(?ModuleName), "E-mail")) .
Filter(?SLOType = ?SLTType) .
Filter(xsd:dateTime(?trackTime) >= xsd:dateTime("2012-08-15T12:00:00") && ?trackTime < xsd:dateTime("2012-08-15T13:00:00")) .
Filter(?DayName = ?SLTDayName || (xsd:dateTime("2012-08-15T00:00:00") = ?HolidayDate && xsd:dateTime(?trackTime) >= xsd:dateTime("2012-08-15T12:00:00") && xsd:dateTime(?trackTime) < xsd:dateTime("2012-08-15T14:00:00")))
}
GROUP BY ?ModuleName ?SLAName ?SLOName ?SLOTypeName ?SLOTHV
HAVING (?AVGTrackValue < ?SLOTHV)
В потеге 4.2 этот запрос работает без проблем и возвращает результат в течение 1 секунды. Также проверка синтаксиса с помощью SPARQLer Query Validator (http://www.sparql.org/query-validator.html) говорит о том, что запрос SPARQL является допустимым. Но с движком jena arq обработка запросов все время застревает в ожидании набора результатов. Я попробовал это с jena-arq-2.9.1 из командной строки, а также в приложении Java с следующим кодом:
Query q = QueryFactory.create(queryString);
QueryExecution qexec = QueryExecutionFactory.create(q, currentOntologyModel);
try {
ResultSet results = qexec.execSelect();
while (results.hasNext()) {
QuerySolution soln = results.nextSolution();
.
.
.
<some other code>
.
.
.
}
}
} finally {
qexec.close();
}
Может быть, у кого-то есть идея, в чем проблема.
2 ответа
Предположительно, данные находятся в памяти.
Похоже, оптимизатор запросов не находит эффективный план. Все несвязанные rdf:type
в начале, возможно, вызывает расчет промежуточных перекрестных продуктов, которые неэффективны.
Может помочь переупорядочение тройных шаблонов (возможно, переместит rdf: type в конец? Сам по себе запрос недостаточно, чтобы знать - это зависит от данных). Если вы нашли более быстрый заказ, пожалуйста, отправьте его в список пользователей jena на Apache.
Спасибо за ваш ответ Энди. Кажется, это проблема с планом выполнения. Теперь я использую вспомогательный выбор, чтобы получить данные для?SLT, и запрос работает отлично. Это запрос, который работает сейчас:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX :<http://www.test.at/DA.owl#>
SELECT ?ModuleName ?SLAName ?SLOName ?SLOTypeName ?SLOTHV (AVG(DISTINCT ?SLTTV) AS ?AVGTrackValue) (COUNT(DISTINCT ?SLT) AS ?SLTCOUNT)
WHERE {
?Module rdf:type :ServiceModule .
?SLA rdf:type :ServiceLevelAgreement.
?SLO rdf:type :ServiceLevelObjective .
?Day rdf:type :Day .
?Holiday rdf:type :Holiday .
?rel1 rdf:type :RelationFact .
?rel3 rdf:type :RelationFact .
?rel4 rdf:type :RelationFact .
?rel5 rdf:type :RelationFact .
?Module :hasName ?ModuleName .
?SLA :hasName ?SLAName .
?SLO :hasName ?SLOName .
?SLO :hasType ?SLOType .
?SLO :hasThresholdValue ?SLOTHV .
?SLOType :hasName ?SLOTypeName .
?SLT :hasDayName ?SLTDayName .
?SLT :hasType ?SLTType .
?SLT :hasTrackedDateTime ?trackTime .
?SLT :hasTrackedValue ?SLTTV .
?Day :hasDayName ?DayName .
?Holiday :hasDate ?HolidayDate .
?Holiday :hasStartTime ?HolidayStartTime .
?Holiday :hasEndTime ?HolidayEndTime .
?rel1 :hasParent ?Module .
?rel1 :hasChild ?SLA .
?rel3 :hasParent ?SLA .
?rel3 :hasChild ?SLO .
?rel4 :hasParent ?SLA .
?rel4 :hasChild ?Day .
?rel5 :hasParent ?SLA .
?rel5 :hasChild ?Holiday .
{
SELECT ?SLT ?SLTType ?ModuleName
WHERE {
?SLT rdf:type :ServiceLevelTracking .
?rel2 rdf:type :RelationFact .
?Module :hasName ?ModuleName .
Filter(regex(str(?ModuleName), "E-mail")) .
?rel2 :hasParent ?Module.
?rel2 :hasChild ?SLT
}
}
Filter(?SLOType = ?SLTType) .
Filter(xsd:dateTime(?trackTime) >= xsd:dateTime("2012-08-15T12:00:00") && ?trackTime < xsd:dateTime("2012-08-15T13:00:00")) .
Filter(?DayName = ?SLTDayName || (xsd:dateTime("2012-08-15T00:00:00") = ?HolidayDate && xsd:dateTime(?trackTime) >= xsd:dateTime("2012-08-15T12:00:00") && xsd:dateTime(?trackTime) < xsd:dateTime("2012-08-15T14:00:00")))
}
GROUP BY ?ModuleName ?SLAName ?SLOName ?SLOTypeName ?SLOTHV
HAVING (?AVGTrackValue < ?SLOTHV)