Skip to content

Commit 1b39bf2

Browse files
galdretonsky
authored andcommitted
Query: shortcircuit clause resolution when result is guaranteed to be 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.
1 parent 78cb86d commit 1b39bf2

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

bench/datascript/bench/datascript.cljc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,19 @@
110110
[?e :sex :male]]
111111
@*db100k)))
112112

113+
(defn bench-q5-shortcircuit []
114+
(bench/bench
115+
(d/q '[:find ?e ?n ?l ?a ?s ?al
116+
:in $ ?n ?a
117+
:where [?e :name ?n]
118+
[?e :age ?a]
119+
[?e :last-name ?l]
120+
[?e :sex ?s]
121+
[?e :alias ?al]]
122+
@*db100k
123+
"Anastasia"
124+
35)))
125+
113126
(defn bench-qpred1 []
114127
(bench/bench
115128
(d/q '[:find ?e ?s
@@ -226,6 +239,7 @@
226239
"q2" bench-q2
227240
"q3" bench-q3
228241
"q4" bench-q4
242+
"q5-shortcircuit" bench-q5-shortcircuit
229243
"qpred1" bench-qpred1
230244
"qpred2" bench-qpred2
231245
"pull-one-entities" bench-pull-one-entities
@@ -277,6 +291,7 @@
277291
(bench-q2)
278292
(bench-q3)
279293
(bench-q4)
294+
(bench-q5-shortcircuit)
280295
(bench-qpred1)
281296
(bench-qpred2)
282297
(bench-pull-one-entities)
@@ -298,4 +313,4 @@
298313
(bench-rules-long-30x3)
299314
(bench-rules-long-30x5)
300315
(bench-freeze)
301-
(bench-thaw))
316+
(bench-thaw))

src/datascript/query.cljc

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -791,12 +791,14 @@
791791
(update context :rels collapse-rels relation))))))
792792

793793
(defn resolve-clause [context clause]
794-
(if (rule? context clause)
795-
(if (source? (first clause))
796-
(binding [*implicit-source* (get (:sources context) (first clause))]
797-
(resolve-clause context (next clause)))
798-
(update context :rels collapse-rels (solve-rule context clause)))
799-
(-resolve-clause context clause)))
794+
(if (->> (:rels context) (some (comp empty? :tuples)))
795+
context ; The result is empty; short-circuit processing
796+
(if (rule? context clause)
797+
(if (source? (first clause))
798+
(binding [*implicit-source* (get (:sources context) (first clause))]
799+
(resolve-clause context (next clause)))
800+
(update context :rels collapse-rels (solve-rule context clause)))
801+
(-resolve-clause context clause))))
800802

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

0 commit comments

Comments
 (0)