Skip to content

Commit

Permalink
Query: shortcircuit clause resolution when result is guaranteed to be…
Browse files Browse the repository at this point in the history
… empty.

The `-collect` fn, run at the end of a query, correctly shortcircuits with the
following comment: "one empty rel means final set has to be empty"

However, while processing the query clauses, there was no shortcircuit.
Also, since the implementation of `lookup-pattern` is agnostic to
existing rels, this means that attempts to write short-circuiting
clauses at the top of a complex query have very little effect: the
query engine will continue querying the indexes for every tuple that
could possibly match every clause.

This adds a shortcircuit in `resolve-clause` if any existing relation
is empty. The check is cheap, and it should provide a substantial
performance boost in many common cases.
  • Loading branch information
galdre authored and tonsky committed Feb 14, 2024
1 parent 78cb86d commit 1b39bf2
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
17 changes: 16 additions & 1 deletion bench/datascript/bench/datascript.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@
[?e :sex :male]]
@*db100k)))

(defn bench-q5-shortcircuit []
(bench/bench
(d/q '[:find ?e ?n ?l ?a ?s ?al
:in $ ?n ?a
:where [?e :name ?n]
[?e :age ?a]
[?e :last-name ?l]
[?e :sex ?s]
[?e :alias ?al]]
@*db100k
"Anastasia"
35)))

(defn bench-qpred1 []
(bench/bench
(d/q '[:find ?e ?s
Expand Down Expand Up @@ -226,6 +239,7 @@
"q2" bench-q2
"q3" bench-q3
"q4" bench-q4
"q5-shortcircuit" bench-q5-shortcircuit
"qpred1" bench-qpred1
"qpred2" bench-qpred2
"pull-one-entities" bench-pull-one-entities
Expand Down Expand Up @@ -277,6 +291,7 @@
(bench-q2)
(bench-q3)
(bench-q4)
(bench-q5-shortcircuit)
(bench-qpred1)
(bench-qpred2)
(bench-pull-one-entities)
Expand All @@ -298,4 +313,4 @@
(bench-rules-long-30x3)
(bench-rules-long-30x5)
(bench-freeze)
(bench-thaw))
(bench-thaw))
14 changes: 8 additions & 6 deletions src/datascript/query.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -791,12 +791,14 @@
(update context :rels collapse-rels relation))))))

(defn resolve-clause [context clause]
(if (rule? context clause)
(if (source? (first clause))
(binding [*implicit-source* (get (:sources context) (first clause))]
(resolve-clause context (next clause)))
(update context :rels collapse-rels (solve-rule context clause)))
(-resolve-clause context clause)))
(if (->> (:rels context) (some (comp empty? :tuples)))
context ; The result is empty; short-circuit processing
(if (rule? context clause)
(if (source? (first clause))
(binding [*implicit-source* (get (:sources context) (first clause))]
(resolve-clause context (next clause)))
(update context :rels collapse-rels (solve-rule context clause)))
(-resolve-clause context clause))))

(defn -q [context clauses]
(binding [*implicit-source* (get (:sources context) '$)]
Expand Down

0 comments on commit 1b39bf2

Please sign in to comment.