【问题标题】:Difference in performance between using VALUES keyword and using directly the URI in the query?在查询中使用 VALUES 关键字和直接使用 URI 之间的性能差异?
【发布时间】:2019-07-08 23:27:41
【问题描述】:

我有一个相当复杂的 SPARQL 查询,其结构如下所述,涉及多个图形模式 UNION 和嵌套 FILTER NOT EXISTS

我希望查询保持通用,并且我希望能够在执行时为某些变量注入值,我的想法是在查询末尾附加一个VALUES 关键字来指定某些变量的值查询中的变量。在下面的结构中,我设置了?x 的值,并说明了查询中?x 适用的所有位置。

但是,在 Fuseki 中,我看到执行这样的查询大约需要 4 到 5 秒,但是手动将查询中的 ?x 变量替换为 URI,而不是指定 VALUES 子句,使其运行起来非常快。

  • 我一直认为在WHERE 子句末尾使用VALUES 关键字就像为某些变量设置内联值,所以我希望使用VALUES 子句或用它们对应的URI 替换变量是在查询执行方面也是如此。有人可以确认VALUES 关键字的预期行为吗?还要解释在WHERE 子句之外或WHERE 子句内部使用它的区别?
  • 使用VALUES 设置的变量出现在FILTER NOT EXISTS 子句中这一事实是否有所改变?
  • 您能否确认这是满足上述要求的正确方法(我希望查询保持通用,并且希望能够在执行时为某些变量注入值)?
  • 这种行为是否可能特定于 Fuseki 处理 VALUES 的方式?

谢谢!

SELECT DISTINCT ...
WHERE {
    # ?x ...
    # ... basic graph pattern here 

    {
      {
        # ... basic graph pattern here 

        FILTER NOT EXISTS {
            # ?x ...
            # ... basic graph pattern here
        }

        FILTER NOT EXISTS {
            # ... basic graph pattern here
            FILTER NOT EXISTS {
                # ?x ...
                # ... basic graph pattern here
            }
        }       
      }
      UNION
      {
        ?x ...
        # ... basic graph pattern here
      }
      UNION
      {
        # ... basic graph pattern here

        FILTER NOT EXISTS {
            ?x ...
            # ... basic graph pattern here
        }

        FILTER NOT EXISTS {
            # ... basic graph pattern here
            FILTER NOT EXISTS {
                ?x ...
                # ... basic graph pattern here
            }
        }
      }
      UNION
      {
        ?x ...
      }
    }
}
VALUES ?x { <http://example.com/Foo> }

【问题讨论】:

    标签: sparql rdf jena fuseki


    【解决方案1】:

    不应该是一个答案,但在 cmets 中格式化是不可能的......

    代数树至少有一些明显的区别。如何处理这可能是特定于实现的。 Andy 比我更了解,希望能给出更有用的答案。

    没有VALUES:

    查询

    SELECT  ?s ?o
    WHERE
      {   { <test_val>  <p>  ?o }
        UNION
          { <test_val>  <p>  ?o
            FILTER NOT EXISTS { <test_val>  a                   ?type }
          }
      }
    

    代数树(优化)

    (base <http://example/base/>
      (project (?s ?o)
        (union
          (bgp (triple <test_val> <p> ?o))
          (filter (notexists (bgp (triple <test_val> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type)))
            (bgp (triple <test_val> <p> ?o))))))
    

    VALUES

    查询

    SELECT  ?s ?o
    WHERE
      {   { ?s  <p>  ?o }
        UNION
          { ?s  <p>  ?o
            FILTER NOT EXISTS { ?s  a                     ?type }
          }
      }
    VALUES ?s { <test_val> }
    

    代数树

    (base <http://example/base/>
      (project (?s ?o)
        (join
          (union
            (bgp (triple ?s <p> ?o))
            (filter (notexists (bgp (triple ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type)))
              (bgp (triple ?s <p> ?o))))
          (table (vars ?s)
            (row [?s <test_val>])
          ))))
    

    代数树(优化)

    (base <http://example/base/>
      (project (?s ?o)
        (sequence
          (table (vars ?s)
            (row [?s <test_val>])
          )
          (union
            (bgp (triple ?s <p> ?o))
            (filter (notexists (bgp (triple ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type)))
              (bgp (triple ?s <p> ?o)))))))
    

    【讨论】:

    • VALUES 最后是“像设置变量”,但不一样。优化器会尝试将值推入,但并非在所有情况下都会发生这种情况,因为它会改变语义。在复杂的查询中,即使知道数据,也有更高的阻塞模式发生的可能性,您知道不会发生更改的语义。有两件事可以尝试:(1)将 VALUES 放在您的意思是它们旁边的位置它们影响的变量,(2) QueryTransformOps 类,它根据变量到值的映射重写查询。
    • 谢谢你知道这真的很有用。由于此功能是我所做工作的关键,因此我真的需要了解使用 VALUES 与在查询中用 URI 替换变量不同的情况,并且会为此提出一个单独的问题。使用 QueryTransformOps 可能会有所帮助,尽管我也可以进行 RegEx 搜索/替换。我不能将 VALUES 放在查询中需要它的任何地方,因为查询字符串在文件中外部化,并且值是在运行时根据上下文设置的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 2020-02-04
    • 2016-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-29
    相关资源
    最近更新 更多