SPARQL加速联合查询

时间:2017-07-27 16:29:27

标签: query-optimization sparql wikidata graphdb federated-queries

我有自己的数据集,我想在SPARQL中执行联合查询。这是查询:

PREFIX : <http://myURIsNamespace#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX ps: <http://www.wikidata.org/prop/statement/>
PREFIX pq: <http://www.wikidata.org/prop/qualifier/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>

select * where { 
    ?bioentity :hasMutatedVersionOf ?gene .
    ?gene :partOf wd:Q430258 .

    SERVICE <https://query.wikidata.org/sparql> { 
        ?gene p:P644 ?statement; 
              wdt:P31 wd:Q7187 ;
              wdt:P703 wd:Q15978631 ;
              wdt:P1057 wd:Q430258 .
        ?statement ps:P644 ?start .
        ?statement pq:P659 wd:Q20966585 .

        ?gene p:P645 ?statement2. 
        ?statement2 ps:P645 ?end .
        ?statement2 pq:P659 wd:Q20966585 .
        FILTER (xsd:integer(?start)>21000000 && xsd:integer(?start)<30000000)  
    }

}

我通过graphDB SPARQL接口运行查询,但它真的很慢。返回8条记录需要一分多钟。如果我将查询分成两部分,那么它们的速度非常快。

查询#1

select * where { 
    ?bioentity :hasMutatedVersionOf ?gene .
    ?gene :partOf wd:Q430258 .          

}

以0.1秒计的56条记录

查询#2

select * where { 
     SERVICE <https://query.wikidata.org/sparql> { 
        ?gene p:P644 ?statement; 
              wdt:P31 wd:Q7187 ;
              wdt:P703 wd:Q15978631 ;
              wdt:P1057 wd:Q430258 .
        ?statement ps:P644 ?start .
        ?statement pq:P659 wd:Q20966585 .

        ?gene p:P645 ?statement2. 
        ?statement2 ps:P645 ?end .
        ?statement2 pq:P659 wd:Q20966585 .
        FILTER (xsd:integer(?start)>21000000 && xsd:integer(?start)<30000000)  
    }       

}

以0.5秒计的158条记录

为什么联盟这么慢?有没有办法优化性能?

1 个答案:

答案 0 :(得分:6)

简短回答

  1. 首先放置SERVICE部分,i。即在?bioentity :hasMutatedVersionOf ?gene .

  2. 之前
  3. 阅读有关该主题的好文章(例如chapter 5this book

  4. 上述文章的相关引用:

      

    3.3.2查询优化和执行

         

    查询运算符的执行顺序会显着影响整体查询评估成本。   除了重要的查询执行时间还有其他   联合方案中与查询相关的方面   优化:

         

    最大限度地降低通信费用。联系人数量   数据源直接影响查询的性能   由于通信开销而执行。但是,减少了   涉及的数据源数量与完整性相关   结果

         

    优化执行本地化。标准查询   链接数据源的接口通常只能够   回答有关其提供的数据的查询。因此,加入   其他数据结果通常需要在查询发布者处完成。如果   可能的话,更好的策略会移动部分结果   将操作合并到数据源,特别是如果它们可以   并行执行。

         

    流式搜索结果。检索完整的结果   在大型数据集上评估查询时,即使使用也可能需要一段时间   优化的执行策略。因此,可以将结果返回为   一旦它们变得可用,可以通过尝试来优化   首先返回相关结果。

    答案很长

    示例数据

    PREFIX : <http://myURIsNamespace#>
    PREFIX wd: <http://www.wikidata.org/entity/>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    PREFIX p: <http://www.wikidata.org/prop/>
    PREFIX ps: <http://www.wikidata.org/prop/statement/>
    PREFIX pq: <http://www.wikidata.org/prop/qualifier/>
    PREFIX wdt: <http://www.wikidata.org/prop/direct/>
    
    INSERT { ?gene rdf:type owl:Thing } 
    WHERE {
        SERVICE <https://query.wikidata.org/sparql> { 
            ?gene p:P644 ?statement; 
                  wdt:P31 wd:Q7187 ;
                  wdt:P703 wd:Q15978631 ;
                  wdt:P1057 wd:Q430258 .
            ?statement ps:P644 ?start .
            ?statement pq:P659 wd:Q20966585 .
            ?gene p:P645 ?statement2. 
            ?statement2 ps:P645 ?end .
            ?statement2 pq:P659 wd:Q20966585 .
            FILTER (xsd:integer(?start)>26000000 && xsd:integer(?start)<30000000)  
        }
    }
    

    三元组的总数为79.请注意,26000000代替21000000

    查询1

    PREFIX : <http://myURIsNamespace#>
    PREFIX wd: <http://www.wikidata.org/entity/>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    PREFIX p: <http://www.wikidata.org/prop/>
    PREFIX ps: <http://www.wikidata.org/prop/statement/>
    PREFIX pq: <http://www.wikidata.org/prop/qualifier/>
    PREFIX wdt: <http://www.wikidata.org/prop/direct/>
    
    SELECT * WHERE {
        ?gene rdf:type owl:Thing .
        SERVICE <https://query.wikidata.org/sparql> { 
            ?gene p:P644 ?statement; 
                  wdt:P31 wd:Q7187 ;
                  wdt:P703 wd:Q15978631 ;
                  wdt:P1057 wd:Q430258 .
            ?statement ps:P644 ?start .
            ?statement pq:P659 wd:Q20966585 .
            ?gene p:P645 ?statement2. 
            ?statement2 ps:P645 ?end .
            ?statement2 pq:P659 wd:Q20966585 .
            FILTER (xsd:integer(?start)>20000000 && xsd:integer(?start)<30000000)  
        }
    }
    

    查询2

    PREFIX : <http://myURIsNamespace#>
    PREFIX wd: <http://www.wikidata.org/entity/>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    PREFIX p: <http://www.wikidata.org/prop/>
    PREFIX ps: <http://www.wikidata.org/prop/statement/>
    PREFIX pq: <http://www.wikidata.org/prop/qualifier/>
    PREFIX wdt: <http://www.wikidata.org/prop/direct/>
    
    SELECT * WHERE {
        SERVICE <https://query.wikidata.org/sparql> { 
            ?gene p:P644 ?statement; 
                  wdt:P31 wd:Q7187 ;
                  wdt:P703 wd:Q15978631 ;
                  wdt:P1057 wd:Q430258 .
            ?statement ps:P644 ?start .
            ?statement pq:P659 wd:Q20966585 .
            ?gene p:P645 ?statement2. 
            ?statement2 ps:P645 ?end .
            ?statement2 pq:P659 wd:Q20966585 .
            FILTER (xsd:integer(?start)>20000000 && xsd:integer(?start)<30000000)  
        }
        ?gene rdf:type owl:Thing
    }
    

    <强>性能

    +------------+---------+---------+
    |            | Query 1 | Query 2 |
    +------------+---------+---------+
    | GraphDB    | 30 sec  |  1 sec  |
    | Blazegraph |  1 sec  |  1 sec  |
    +------------+---------+---------+
    

    GraphDB行为

    执行查询1,GraphDB对Wikidata¹执行79个不同的GET请求:

    Wireshark — packets

    Wireshark — statistics

    这些请求是这种查询:

    SELECT ?start ?statement ?end ?statement2 WHERE {
            <http://www.wikidata.org/entity/Q18031286> p:P644 ?statement; 
                  wdt:P31 wd:Q7187 ;
                  wdt:P703 wd:Q15978631 ;
                  wdt:P1057 wd:Q430258 .
            ?statement ps:P644 ?start .
            ?statement pq:P659 wd:Q20966585 .
            <http://www.wikidata.org/entity/Q18031286> p:P645 ?statement2. 
            ?statement2 ps:P645 ?end .
            ?statement2 pq:P659 wd:Q20966585 .
            FILTER (xsd:integer(?start)>20000000 && xsd:integer(?start)<30000000)
    

    有趣的是,在另一台机器上,GraphDB执行另一种GET请求:

    GET /sparql?queryLn="Sparql"&query=<original_query_service_part>&$gene=<http://www.wikidata.org/entity/Q18031286>
    

    在此请求中,使用了Sesame protocol,这些URL中的绑定不属于SPARQL 1.1 Protocol

    请求的确切类型可能取决于内部reuse.vars.in.subselects参数的值,该参数在Windows和Linux上的默认值可能不同。

    Blazegraph行为

    执行查询1,Blazegraph对Wikidata²执行单POST次请求:

    SELECT  ?gene ?statement ?start ?statement2 ?end
    WHERE {
            ?gene p:P644 ?statement; 
                  wdt:P31 wd:Q7187 ;
                  wdt:P703 wd:Q15978631 ;
                  wdt:P1057 wd:Q430258 .
            ?statement ps:P644 ?start .
            ?statement pq:P659 wd:Q20966585 .
            ?gene p:P645 ?statement2. 
            ?statement2 ps:P645 ?end .
            ?statement2 pq:P659 wd:Q20966585 .
            FILTER (xsd:integer(?start)>20000000 && xsd:integer(?start)<30000000)  
    
    }
    VALUES ( ?gene) {
    ( wd:Q14908148 ) ( wd:Q15320063 ) ( wd:Q17861651 ) ( wd:Q17917753 ) ( wd:Q17928333 )
    ( wd:Q18024923 ) ( wd:Q18026347 ) ( wd:Q18030710 ) ( wd:Q18031220 ) ( wd:Q18031457 )
    ( wd:Q18031551 ) ( wd:Q18031832 ) ( wd:Q18032918 ) ( wd:Q18033094 ) ( wd:Q18033798 )
    ( wd:Q18034311 ) ( wd:Q18035006 ) ( wd:Q18035085 ) ( wd:Q18035609 ) ( wd:Q18036516 )
    ( wd:Q18036676 ) ( wd:Q18037580 ) ( wd:Q18038385 ) ( wd:Q18038459 ) ( wd:Q18038737 )
    ( wd:Q18038763 ) ( wd:Q18039997 ) ( wd:Q18040291 ) ( wd:Q18041261 ) ( wd:Q18041415 )
    ( wd:Q18041558 ) ( wd:Q18045881 ) ( wd:Q18047232 ) ( wd:Q18047373 ) ( wd:Q18047918 )
    ( wd:Q18047966 ) ( wd:Q18048744 ) ( wd:Q18049145 ) ( wd:Q18049164 ) ( wd:Q18053139 )
    ( wd:Q18056540 ) ( wd:Q18057411 ) ( wd:Q18060804 ) ( wd:Q18060856 ) ( wd:Q18060876 )
    ( wd:Q18060905 ) ( wd:Q18060958 ) ( wd:Q20773708 ) ( wd:Q15312971 ) ( wd:Q17860819 )
    ( wd:Q17917713 ) ( wd:Q18026310 ) ( wd:Q18027015 ) ( wd:Q18031286 ) ( wd:Q18032599 )
    ( wd:Q18032797 ) ( wd:Q18035169 ) ( wd:Q18035627 ) ( wd:Q18039938 ) ( wd:Q18041207 )
    ( wd:Q18041512 ) ( wd:Q18041930 ) ( wd:Q18045491 ) ( wd:Q18045762 ) ( wd:Q18046301 )
    ( wd:Q18046472 ) ( wd:Q18046487 ) ( wd:Q18047149 ) ( wd:Q18047491 ) ( wd:Q18047719 )
    ( wd:Q18048527 ) ( wd:Q18049774 ) ( wd:Q18051886 ) ( wd:Q18053875 ) ( wd:Q18056212 )
    ( wd:Q18056538 ) ( wd:Q18065866 ) ( wd:Q20766978 ) ( wd:Q20781543 )
    } 
    

    <强>结论

    使用联合查询时,很难创建有效的执行计划,因为远程模式的选择性是未知的。

    在您的特定情况下,无论是本地还是远程加入结果都应该不是很重要,因为本地和远程结果集都很小。但是,在GraphDB中,远程连接结果效率较低,因为GraphDB不会降低通信成本。

    ¹为了创建屏幕截图,我们使用了<http://query.wikidata.org/sparql>而不是<https://query.wikidata.org/sparql>

    ²在Blazegraph中,人们可能会写hint:Query hint:optimizer "None"以确保顺序评估。