如何用SPARQL在Wikidata查询特定人物?现有查询超时求助
解决Wikidata SPARQL查询超时问题:通过维基百科页面名获取人物信息
原问题与错误
编写的SPARQL查询尝试通过维基百科页面名查询人物信息,但查询超时,抛出java.util.concurrent.TimeoutException。
原查询语句
PREFIX schema: <http://schema.org/> SELECT ?item ?itemLabel ?person ?personLabel ?pic ?givenName ?givenNameLabel ?familyName ?familyNameLabel ?placeOfBirth ?placeOfBirthLabel WHERE { ?person wdt:P31 wd:Q5 . ?person wdt:P18 ?pic . ?person wdt:P735 ?givenName . ?person wdt:P734 ?familyName . ?person wdt:P19 ?placeOfBirth . ?person wdt:P569 ?birthDate . ?item ?label "Einstein"@en . OPTIONAL { ?article schema:about ?cid . ?article schema:inLanguage "en" . ?article schema:isPartOf <https://en.wikipedia.org/> . } SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } } LIMIT 1
超时错误信息
java.util.concurrent.TimeoutException at java.util.concurrent.FutureTask.get(FutureTask.java:205) at com.bigdata.rdf.sail.webapp.BigdataServlet.submitApiTask(BigdataServlet.java:292) at com.bigdata.rdf.sail.webapp.QueryServlet.doSparqlQuery(QueryServlet.java:678) at com.bigdata.rdf.sail.webapp.QueryServlet.doGet(QueryServlet.java:290) at com.bigdata.rdf.sail.webapp.RESTServlet.doGet(RESTServlet.java:240) at com.bigdata.rdf.sail.webapp.MultiTenancyServlet.doGet(MultiTenancyServlet.java:273) at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:865) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1655) at org.wikidata.query.rdf.blazegraph.throttling.ThrottlingFilter.doFilter(ThrottlingFilter.java:320) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642) at org.wikidata.query.rdf.blazegraph.throttling.SystemOverloadFilter.doFilter(SystemOverloadFilter.java:82) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642) at ch.qos.logback.classic.helpers.MDCInsertingServletFilter.doFilter(MDCInsertingServletFilter.java:49) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642) at org.wikidata.query.rdf.blazegraph.filters.QueryEventSenderFilter.doFilter(QueryEventSenderFilter.java:116) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642) at org.wikidata.query.rdf.blazegraph.filters.ClientIPFilter.doFilter(ClientIPFilter.java:43) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642) at org.wikidata.query.rdf.blazegraph.filters.JWTIdentityFilter.doFilter(JWTIdentityFilter.java:66) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642) at org.wikidata.query.rdf.blazegraph.filters.RealAgentFilter.doFilter(RealAgentFilter.java:33) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642) at org.wikidata.query.rdf.blazegraph.filters.RequestConcurrencyFilter.doFilter(RequestConcurrencyFilter.java:50) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1634) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1340) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1242) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144) at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220) at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) at org.eclipse.jetty.server.Server.handle(Server.java:503) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103) at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126) at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765) at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683) at java.lang.Thread.run(Thread.java:750)
问题分析
- 无关联的笛卡尔积:原查询中
?item ?label "Einstein"@en没有和?person建立关联,导致系统会遍历所有包含"Einstein"标签的条目,再与所有人物条目(wdt:P31 wd:Q5)做笛卡尔积,数据量暴增直接引发超时。 - 冗余的可选片段:
OPTIONAL块中的?cid未与主查询中的任何变量关联,属于完全冗余的查询逻辑,徒增计算负担。 - 查询顺序不合理:先筛选所有人物再匹配标签,而非先定位目标人物再获取属性,效率极低。
优化后的查询语句
PREFIX schema: <http://schema.org/> SELECT ?person ?personLabel ?pic ?givenName ?givenNameLabel ?familyName ?familyNameLabel ?placeOfBirth ?placeOfBirthLabel WHERE { # 通过维基百科页面标题定位人物实体 ?article schema:about ?person ; schema:inLanguage "en" ; schema:isPartOf <https://en.wikipedia.org/> ; schema:name "Einstein"@en . # 约束人物实体属性 ?person wdt:P31 wd:Q5 ; wdt:P18 ?pic ; wdt:P735 ?givenName ; wdt:P734 ?familyName ; wdt:P19 ?placeOfBirth . SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } }
优化点解释
- 直接关联维基百科页面与人物实体:通过
schema:name指定维基百科页面标题,结合schema:about直接定位到对应的Wikidata人物实体,避免笛卡尔积。 - 移除冗余逻辑:删掉无关联的
?item和无效的OPTIONAL块,简化查询结构。 - 调整查询顺序:先定位目标人物,再获取其属性,大幅减少需要遍历的数据量,提升查询效率。
内容的提问来源于stack exchange,提问作者Lance Pollard
相关产品推荐
相关产品推荐

