Оптимизация запроса SPARQL. [Расчетное время выполнения превышает ограничение в 1500 (сек) ]

#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! 🙂