What is the difference between a "merge" and a "one by one" execution of SPARQL queries across named graphs?

By wrapping one or more triple patterns in a GRAPH ?g { ... } pattern, the triple patterns inside this "graph group pattern" will be restricted to the specified named graph, ?g. Lacking the GRAPH ?g { ... }, the triples may be found in different named graphs. Using graph group patterns can thus dramatically reduce the amount of data to be processed for all triple patterns after the first in join order, so it's typically faster.

Note -- The "default graph" in Virtuoso is not a union of all graphs; it is a sum. This means that Virtuoso's behavior differs slightly from the SPARQL spec, in that some duplicate result rows may appear if the same values appear as { ?s ?p ?o } in two or more different graphs). (Results perfectly conforming to the SPARQL spec would leave out these duplicate rows.)

This query will deliver matching triples from any and all named graphs in the Virtuoso store --


[PREFIXes here]
  SELECT ?serial ?sr ?ct1 ?ct2 
  WHERE 
    {
      ?sr      a                    dm:SessionRecord 
    . ?sr      dm:hasDataSnapshot   ?snap 
    . ?device  dm:hasSessionRecord  ?sr 
    . ?device  dm:hasSerialNumber   ?serial 
    . [etc.] 
    }

With the added GRAPH ?g { ... } patterns below, only matching triples from the specified named graph(s) will be returned.


[PREFIXes here]
SELECT ?serial ?sr ?ct1 ?ct2 
WHERE 
  {
    GRAPH ?g1 { ?sr      a                    dm:SessionRecord }
    GRAPH ?g2 { ?sr      dm:hasDataSnapshot   ?snap            }
    GRAPH ?g3 { ?device  dm:hasSessionRecord  ?sr              }
    GRAPH ?g4 { ?device  dm:hasSerialNumber   ?serial          }
    [etc.] 
  }

Related