I have a query that I would like to simplify and still have it perform well.
The simple form of the query is as follows and I add additional filters depending on which subjects are requested,
But this performs quite poorly.
SELECT *
WHERE {
?s ?p ?o
OPTIONAL {
?o ?pp ?oo
}
FILTER (
?s = <ex:id/12763>
|| ?s = <ex:id/15475>
|| ?s = <ex:id/26077>
|| ?s = <ex:id/10005>
|| ?s = <ex:id/12756>
|| ?s = <ex:id/29401>
|| ?s = <ex:id/14658>
|| ?s = <ex:id/29199>
|| ?s = <ex:id/53481>
|| ?s = <ex:id/41602>
)
}
Query returned 60 results in 00:00:16.530
The Query Plan:
Projection(?s, ?p, ?o, ?pp, ?oo) [#38.4M]
`ā MergeJoinOuter(?o) [#38.4M]
+ā Filter((?s = <ex:id/12763> || (?s = <ex:id/15475> || (?s = <ex:id/26077> || (?s = <ex:id/10005> || (?s = <ex:id/12756> || (?s = <ex:id/29401> || (?s = <ex:id/14658> || (?s = <ex:id/29199> || (?s = <ex:id/53481> || ?s = <ex:id/41602>)))))))))) [#0]
ā `ā Scan[OSPC](?s, ?p, ?o) [#38.4M]
`ā Scan[SPOC](?o, ?pp, ?oo) [#38.4M]
I rewrote it as follows, and it performs well, however its a huge ugly query.:
Select *
WHERE {
{
select (<ex:id/12763> as ?s) ?p ?o
WHERE{ <ex:id/12763> ?p ?o.
OPTIONAL { ?o ?pp ?oo }
}
}
UNION
{
select (<ex:id/15475> as ?s) ?p ?o
WHERE{ <ex:id/15475> ?p ?o.
OPTIONAL { ?o ?pp ?oo }
}
}
UNION
{
select (<ex:id/26077> as ?s) ?p ?o
WHERE{ <ex:id/26077> ?p ?o.
OPTIONAL { ?o ?pp ?oo }
}
}
UNION
{
select (<ex:id/10005> as ?s) ?p ?o
WHERE{ <ex:id/10005> ?p ?o.
OPTIONAL { ?o ?pp ?oo }
}
}
UNION
{
select (<ex:id/12756> as ?s) ?p ?o
WHERE{ <ex:id/12756> ?p ?o.
OPTIONAL { ?o ?pp ?oo }
}
}
UNION
{
select (<ex:id/29401> as ?s) ?p ?o
WHERE{ <ex:id/29401> ?p ?o.
OPTIONAL { ?o ?pp ?oo }
}
}
UNION
{
select (<ex:id/14658> as ?s) ?p ?o
WHERE{ <ex:id/14658> ?p ?o.
OPTIONAL { ?o ?pp ?oo }
}
}
UNION
{
select (<ex:id/29199> as ?s) ?p ?o
WHERE{ <ex:id/29199> ?p ?o.
OPTIONAL { ?o ?pp ?oo }
}
}
UNION
{
select (<ex:id/53481> as ?s) ?p ?o
WHERE{ <ex:id/53481> ?p ?o.
OPTIONAL { ?o ?pp ?oo }
}
}
UNION
{
select (<ex:id/41602> as ?s) ?p ?o
WHERE{ <ex:id/41602> ?p ?o.
OPTIONAL { ?o ?pp ?oo }
}
}
}
This produces the same results and runs quickly.
Query returned 60 results in 00:00:00.167
The Query Plan:
Projection(?s, ?p, ?o) [#60]
`ā Union [#60]
+ā Projection(<ex:id/12763> AS ?s, ?p, ?o) [#6]
ā `ā MergeJoinOuter(?o) [#6]
ā +ā Sort(?o) [#6]
ā ā `ā Scan[SPOC](<ex:id/12763>, ?p, ?o) [#6]
ā `ā Scan[SC](?o, _, _) [#8.9M]
`ā Union [#54]
+ā Projection(<ex:id/15475> AS ?s, ?p, ?o) [#6]
ā `ā MergeJoinOuter(?o) [#6]
ā +ā Sort(?o) [#6]
ā ā `ā Scan[SPOC](<ex:id/15475>, ?p, ?o) [#6]
ā `ā Scan[SC](?o, _, _) [#8.9M]
`ā Union [#48]
+ā Projection(<ex:id/26077> AS ?s, ?p, ?o) [#6]
ā `ā MergeJoinOuter(?o) [#6]
ā +ā Sort(?o) [#6]
ā ā `ā Scan[SPOC](<ex:id/26077>, ?p, ?o) [#6]
ā `ā Scan[SC](?o, _, _) [#8.9M]
`ā Union [#42]
+ā Projection(<ex:id/10005> AS ?s, ?p, ?o) [#6]
ā `ā MergeJoinOuter(?o) [#6]
ā +ā Sort(?o) [#6]
ā ā `ā Scan[SPOC](<ex:id/10005>, ?p, ?o) [#6]
ā `ā Scan[SC](?o, _, _) [#8.9M]
`ā Union [#36]
+ā Projection(<ex:id/12756> AS ?s, ?p, ?o) [#6]
ā `ā MergeJoinOuter(?o) [#6]
ā +ā Sort(?o) [#6]
ā ā `ā Scan[SPOC](<ex:id/12756>, ?p, ?o) [#6]
ā `ā Scan[SC](?o, _, _) [#8.9M]
`ā Union [#30]
+ā Projection(<ex:id/29401> AS ?s, ?p, ?o) [#6]
ā `ā MergeJoinOuter(?o) [#6]
ā +ā Sort(?o) [#6]
ā ā `ā Scan[SPOC](<ex:id/29401>, ?p, ?o) [#6]
ā `ā Scan[SC](?o, _, _) [#8.9M]
`ā Union [#24]
+ā Projection(<ex:id/14658> AS ?s, ?p, ?o) [#6]
ā `ā MergeJoinOuter(?o) [#6]
ā +ā Sort(?o) [#6]
ā ā `ā Scan[SPOC](<ex:id/14658>, ?p, ?o) [#6]
ā `ā Scan[SC](?o, _, _) [#8.9M]
`ā Union [#18]
+ā Projection(<ex:id/29199> AS ?s, ?p, ?o) [#6]
ā `ā MergeJoinOuter(?o) [#6]
ā +ā Sort(?o) [#6]
ā ā `ā Scan[SPOC](<ex:id/29199>, ?p, ?o) [#6]
ā `ā Scan[SC](?o, _, _) [#8.9M]
`ā Union [#12]
+ā Projection(<ex:id/53481> AS ?s, ?p, ?o) [#6]
ā `ā MergeJoinOuter(?o) [#6]
ā +ā Sort(?o) [#6]
ā ā `ā Scan[SPOC](<ex:id/53481>, ?p, ?o) [#6]
ā `ā Scan[SC](?o, _, _) [#8.9M]
`ā Projection(<ex:id/41602> AS ?s, ?p, ?o) [#6]
`ā MergeJoinOuter(?o) [#6]
+ā Sort(?o) [#6]
ā `ā Scan[SPOC](<ex:id/41602>, ?p, ?o) [#6]
`ā Scan[SC](?o, _, _) [#8.9M]
Is there a better way to do this?