#query-optimization #semantic-web #sparql #dbpedia
#оптимизация запроса #semantic-web #sparql #dbpedia
Вопрос:
Я пытаюсь выполнить этот запрос на http://dbpedia.org/sparql но я получаю сообщение об ошибке, что мой запрос слишком дорогой. Когда я запускаю корыто запроса http://dbpedia.org/snorql / Я получаю:
The estimated execution time 25012730 (sec) exceeds the limit of 1500 (sec) ...
При запуске запроса через мой скрипт python с использованием SPARQLWrapper я просто получаю HTTP 500.
Я полагаю, мне нужно что-то сделать для оптимизации моего запроса SPARQL. Мне нужны данные для перебора по образовательным учреждениям и импорта их в локальную базу данных, возможно, я неправильно использую SPARQL и должен сделать это принципиально другим способом.
Надеюсь, кто-нибудь сможет мне помочь!
Запрос
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX : <http://dbpedia.org/resource/>
PREFIX dbpedia2: <http://dbpedia.org/property/>
PREFIX dbpedia: <http://dbpedia.org/>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT DISTINCT ?uri
?name
?homepage
?student_count
?native_name
?city
?country
?type
?lat ?long
?image
WHERE {
?uri rdf:type dbpedia-owl:EducationalInstitution .
?uri foaf:name ?name .
OPTIONAL { ?uri foaf:homepage ?homepage } .
OPTIONAL { ?uri dbpedia-owl:numberOfStudents ?student_count } .
OPTIONAL { ?uri dbpprop:nativeName ?native_name } .
OPTIONAL { ?uri dbpprop:city ?city } .
OPTIONAL { ?uri dbpprop:country ?country } .
OPTIONAL { ?uri dbpprop:type ?type } .
OPTIONAL { ?uri geo:lat ?lat . ?uri geo:long ?long } .
OPTIONAL { ?uri foaf:depiction ?image } .
}
ORDER BY ?uri
LIMIT 20 OFFSET 10
Ответ №1:
Забудьте об этом. Вы не сможете вернуть этот запрос из dbpedia с помощью всего одного SPARQL. Эти опции очень дороги.
Чтобы обойти это, вам нужно сначала запустить что-то вроде:
SELECT DISTINCT ?uri WHERE {
?uri rdf:type dbpedia-owl:EducationalInstitution .
?uri foaf:name ?name .
} ORDER BY ?uri
LIMIT 20 OFFSET 10
Затем выполните итерацию по результирующему набору этого запроса , чтобы сформировать отдельные запросы для каждого dbpedia-owl:EducationalInstitution
, такие как … (обратите внимание на фильтр в конце запроса):
SELECT DISTINCT ?uri
?name
?homepage
?student_count
?native_name
?city
?country
?type
?lat ?long
?image
WHERE {
?uri rdf:type dbpedia-owl:EducationalInstitution .
?uri foaf:name ?name .
OPTIONAL { ?uri foaf:homepage ?homepage } .
OPTIONAL { ?uri dbpedia-owl:numberOfStudents ?student_count } .
OPTIONAL { ?uri dbpprop:nativeName ?native_name } .
OPTIONAL { ?uri dbpprop:city ?city } .
OPTIONAL { ?uri dbpprop:country ?country } .
OPTIONAL { ?uri dbpprop:type ?type } .
OPTIONAL { ?uri geo:lat ?lat . ?uri geo:long ?long } .
OPTIONAL { ?uri foaf:depiction ?image } .
FILTER (?uri = <http://dbpedia.org/resource/École_élémentaire_Marie-Curie>)
}
Где <http://dbpedia.org/resource/École_élémentaire_Marie-Curie>
было получено из первого запроса.
… и да, это будет медленно, и вы, возможно, не сможете запустить это для онлайн-приложения. Совет: попробуйте разработать какой-нибудь механизм кэширования, который располагался бы между вашим приложением и конечной точкой dbpedia SPARQL.
Комментарии:
1. Выполнение запроса заняло от 3 минут до 42 часов, но, похоже, сейчас он работает стабильно. Спасибо.
Ответ №2:
Не пытайтесь получить весь набор данных сразу! Добавьте предложение LIMIT
and OFFSET
и используйте их для перелистывания данных.
С LIMIT 50
добавлением я получаю результат для вашего запроса почти мгновенно, мне удалось увеличить ограничение намного выше этого и все еще получать ответ, так что поиграйте с этим. Как только вы найдете подходящий вам размер страницы, просто повторите запрос с OFFSET
, пока не получите больше результатов, например
SELECT * WHERE { ... } LIMIT 100
SELECT * WHERE { ... } LIMIT 100 OFFSET 100
...
Комментарии:
1. Я думаю, проблема не в размере страницы, а
order by
вместе со смещением. По мере увеличения смещения заказ становится все более и более дорогим. Не совсем уверен в этом, но это мое предположение.2. Я уже использовал limit и offset для пролистывания данных, запросы по-прежнему были дорогостоящими, даже при попытке получить только 1 ресурс.
3. @msalvadores поскольку я интерпретирую документацию, в ней говорится, что вы должны указывать ORDER BY, когда у вас есть ОГРАНИЧЕНИЕ и СМЕЩЕНИЕ в вашем запросе. » Использование LIMIT и OFFSET для выбора различных подмножеств решений запроса не будет полезным, если порядок не будет сделан предсказуемым с помощью ORDER BY «.
4. @Johan Да и нет, процессор SPARQL не требуется для сохранения порядка решений, если не используется
ORDER BY
an, поэтому теоретически, выполняя запрос сLIMIT 5
, а затемLIMIT 5 OFFSET 5
безORDER BY
, процессор может законно возвращать те же 5 результатов. На практике часто будет иметь место некоторый неявный порядок решений как побочный эффект того, как оценивается запрос, поэтому использовать их безORDER BY
, как правило, безопаснее и быстрее
Ответ №3:
Если вы знаете точный URI (например, из предыдущего запроса), то ввод URI непосредственно в предложение where быстрее (по крайней мере, по моему опыту), чем ввод URI в ФИЛЬТР.
например, предпочесть:
WHERE { <http:/...> ... }
более
WHERE { ?uri .... FILTER (?uri...)
Также я обнаружил, что UNION на самом деле работают быстрее, чем фильтры, предназначенные для сопоставления нескольких ресурсов.
То, что мы сейчас используем SPARQL, не означает, что мы можем забыть кошмары настройки SQL, добро пожаловать в удивительный мир настройки SPARQL! 🙂