"DPLL" is Worst Case Optimal

Florent Capelli, Oliver Irwin, Sylvain Salvati

CRIL, Université d’Artois

Séminaire du CRIL

11 November 2025

Joining relations

Joining like a DB Dude

Q≔R(x1,x2)∧S(x1,x3)∧T(x2,x3)Q \coloneq R(x_1, x_2) \wedge S(x_1, x_3) \wedge T(x_2, x_3)

RR x1x_1 x2x_2
0 0
0 1
2 1
SS x1x_1 x3x_3
0 0
0 2
2 3
TT x2x_2 x3x_3
0 2
1 0
1 2
  • Devise a query plan: (R⋈S)(R \bowtie S) ⋈T\bowtie T
  • Materialize the intermediate joins.
R⋈SR \bowtie S ⋈T\bowtie T x1x_1 x2x_2 x3x_3
0 0 0
0 0 2
0 1 0
0 1 2
2 1 3

Joining like a SAT Guy

Q≔R(x1,x2)∧S(x1,x3)∧T(x2,x3)Q \coloneq R(x_1, x_2) \wedge S(x_1, x_3) \wedge T(x_2, x_3)

RR x1x_1 x2x_2
0 0
0 1
2 1
SS x1x_1 x3x_3
0 0
0 2
2 3
TT x2x_2 x3x_3
0 2
1 0
1 2

Disruptive poll

In theory, is it better to do a database join like:

  1. A DB Dude
  2. A SAT guy

No confidence vote

  1. Go home, you are not qualified to talk about joins after saying dumb things like that.
  2. This is LE CRIL. We do SAT before breakfast everyday. Some of us even replace sugar with GLUCOSE in their coffee. Tell us the whole story

What is wrong with joining like a pro

Q≔R(x1,x2)∧S(x1,x3)∧T(x2,x3)Q \coloneq R(x_1, x_2) \wedge S(x_1, x_3) \wedge T(x_2, x_3)

Worst scenario for query plans

Consider 𝔻\mathbb{D} on domain D=D1⊎D2⊎D3D = D_1 \uplus D_2 \uplus D_3 with:

RR x1x_1 x2x_2
0 D2D_2
D1D_1 0
SS x1x_1 x3x_3
0 D3D_3
D1D_1 0
TT x2x_2 x3x_3
0 D3D_3
D2D_2 0

Every query plan will materialize a table of size O(N2)O(N^2) but the answer table will never be of size greater than (2N)1.5(2N)^{1.5}.

And the brute?

Domain D=D1⊎D2⊎D3D = D_1 \uplus D_2 \uplus D_3 with 0∉D0 \notin D and |D1|=|D2|=|D3|=N|D_1|=|D_2|=|D_3|=N.

RR x1x_1 x2x_2
0 D2D_2
D1D_1 0
SS x1x_1 x3x_3
0 D3D_3
D1D_1 0
TT x2x_2 x3x_3
0 D3D_3
D2D_2 0

If we do the “else” branches efficiently (e.g. by reading values from one table), the algorithm makes O(N)O(N) recursive calls.

Worst-case optimality

Worst-case optimal join

Q≔R(x1,x2)∧S(x1,x3)∧T(x2,x3)Q \coloneq R(x_1, x_2) \wedge S(x_1, x_3) \wedge T(x_2, x_3)

Ideal complexity: output Q(𝔻)Q(\mathbb{D}) in time O(f(|Q|)⋅|Q(𝔻)|)O(f(|Q|) \cdot |Q(\mathbb{D})|)…

… unlikely to be possible.

Worst case optimal: output Q(𝔻)Q(\mathbb{D}) in time Õ(f(|Q|)⋅N1.5)\tilde{O}(f(|Q|) \cdot N^{1.5}).

NN is the size of the largest input relation and Õ(⋅)\tilde{O}(\cdot) ignores polylog factors.

f(|Q|)f(|Q|): data complexity, ie, QQ is considered constant. Ideally, ff is a reasonable polynomial though.

Worst case value

Consider a join query QQ and all databases for QQ with a bound NN on the table size: 𝒟Q≤N={𝔻∣∀R∈Q,|R𝔻|≤N} \mathcal{D}_{Q}^{\leqslant N}= \{\mathbb{D}\mid \forall R \in Q, |R^\mathbb{D}| \leqslant N\} and let: 𝗐𝖼(Q,N)=𝗌𝗎𝗉𝔻∈𝒟Q≤N|Q(𝔻)| \mathsf{wc}(Q, N) = \mathsf{sup}_{\mathbb{D}\in\mathcal{D}_{Q}^{\leqslant N}}~|Q(\mathbb{D})|

𝗐𝖼(Q,N)\mathsf{wc}(Q,N) is the worst case: the size of the biggest answer set possible with query QQ and databases where each table are bounded by NN.

Worst case examples

We know how to compute ρ(Q)\rho(Q) such that 𝗐𝖼(Q,N)=Õ(Nρ(Q))\mathsf{wc}(Q,N) = \tilde{O}(N^{\rho(Q)}) but we do not need it!

This is known as the AGM-bound

Worst case optimal join (WCOJ) algorithms

A join algorithm is worst case optimal (wrt 𝒟Q≤N\mathcal{D}_{Q}^{\leqslant N}) if for every QQ, N∈ℕN \in \mathbb{N} and 𝔻∈𝒟Q≤N\mathbb{D}\in \mathcal{D}_{Q}^{\leqslant N}, it computes Q(𝔻)Q(\mathbb{D}) in time Õ(f(|Q|)⋅𝗐𝖼(Q,N))\tilde{O}(f(|Q|) \cdot \mathsf{wc}(Q,N))

The DBMS approach is not worst case optimal (triangle example from before).

Existing WCOJ Algorithm

Rich literature:

We prove the worst case optimality of the branch and bound algorithm in an elementary way.

Analysing the brute

Algorithm reminder

Complexity analysis

One recursive call:

  • branch variable xix_i on value d∈𝖽𝗈𝗆d \in \mathsf{dom}
  • filter/project relations with xix_i
  • Binary search in O(log⁡|R|)O(\log |R|) if RR ordered
    (O(1)O(1) possible using tries).
RR x1x_1 x2x_2
▸ 0 0
0 2
▸ 1 0
1 1 ◂
2 0
2 1 ◂

Total complexity: number of recursive calls times Õ(m)\tilde{O}(m) where mm is the number of atoms.

Number of calls: example

  • Nodes: partial assignment τ\tau
  • Here: τ:={x1=0,x2=1}\tau := \{x_1=0, x_2=1\}
  • Not node: partial assignment compatible with every relation
  • τ\tau solution of Q2(𝔻2)Q_2(\mathbb{D}_2): project on x1,x2x_1,x_2.
  • At most: |Q2(𝔻2)||Q_2(\mathbb{D}_2)| such nodes at level 33

Q≔R(x1,x2)∧S(x1,x3)∧T(x2,x3)Q \coloneq R(x_1, x_2) \wedge S(x_1, x_3) \wedge T(x_2, x_3)

RR x1x_1 x2x_2
0 0
0 1
2 1
SS x1x_1 x3x_3
0 0
0 2
2 3
TT x2x_2 x3x_3
0 2
1 0
1 2

Q2≔R2(x1,x2)∧S2(x1)∧T2(x2)Q_2 \coloneq R_2(x_1, x_2) \wedge S_2(x_1) \wedge T_2(x_2)

R2R_2 x1x_1 x2x_2
0 0
0 1
2 1
S2S_2 x1x_1
0
2
T2T_2 x2x_2
0
1

Number of calls in general

  • a call = a node = a partial assignment.
  • τ:=x1=d1,…,xi=di\tau := x_1=d_1, \dots, x_i=d_i current call, not :
    • No inconsistency.
    • R𝔻[τ]R^\mathbb{D}[\tau] not empty for each R∈QR \in Q
    • τ∈Qi(𝔻)\tau \in Q_i(\mathbb{D}) for Qi=⋀R∈Q∏x1…xiRQ_i = \bigwedge_{R\in Q}\prod_{x_1\dots x_i} R
    • ≤∑i=1n|Qi(𝔻)|\leq \sum_{i=1}^n |Q_i(\mathbb{D})| such nodes!
  • τ:=x1=d1,…,xi+1=di+1\tau := x_1=d_1, \dots, x_{i+1}=d_{i+1} current call is :
    • x1=d1,…,xi=dix_1=d_1, \dots, x_{i}=d_i is not ⊥\bot.
    • ≤|𝖽𝗈𝗆|⋅∑i=1n|Qi(𝔻)|\leq |\mathsf{dom}| \cdot \sum_{i=1}^n |Q_i(\mathbb{D})| ⊥\bot-nodes!

At most (|𝖽𝗈𝗆|+1)∑i=1n|Qi(𝔻)|(|\mathsf{dom}|+1) \sum_{i=1}^n |Q_i(\mathbb{D})| calls.

Complexity: Õ(m|𝖽𝗈𝗆|⋅∑i=1n|Qi(𝔻)|)\tilde{O}(m|\mathsf{dom}|\cdot \sum_{i=1}^{n}|Q_i(\mathbb{D})|).

Toward worst case optimality

|Qi(𝔻)|=|⋀R∈Q∏x1…xiR𝔻|=|⋀R∈QR𝔻′|=|Q(𝔻′)|\begin{align*} |Q_i(\mathbb{D})| &= |\bigwedge_{R\in Q}\prod_{x_1\dots x_i} R^\mathbb{D}|\\ &= |\bigwedge_{R\in Q} R^{\mathbb{D}'}| \\ &= |Q(\mathbb{D}')| \end{align*}

where R𝔻′=∏x1…xiR𝔻×{0}XR\x1,…,xiR^{\mathbb{D}'} = \prod_{x_1\dots x_i} R^\mathbb{D}\times \{0\}^{X_R \setminus x_1, \dots, x_i}

Crucial observation:

  • |R𝔻′|=|∏x1…xiR𝔻|≤|R𝔻|≤N|R^{\mathbb{D}'}| = |\prod_{x_1\dots x_i} R^\mathbb{D}| \leq |R^\mathbb{D}| \leq N
  • Hence 𝔻′∈𝒟Q≤N\mathbb{D}' \in \mathcal{D}_{Q}^{\leqslant N}.
  • |Qi(𝔻)|=|Q(𝔻′)|≤𝗐𝖼(Q,N)|Q_i(\mathbb{D})| = |Q(\mathbb{D}')| \leq \mathsf{wc}(Q,N)

𝔻\mathbb{D}

RR x1x_1 x2x_2
0 0
0 1
2 1
SS x1x_1 x3x_3
0 0
0 2
2 3
TT x2x_2 x3x_3
0 2
1 0
1 2

𝔻2\mathbb{D}_2

R2R_2 x1x_1 x2x_2
0 0
0 1
2 1
S2S_2 x1x_1
0
2
T2T_2 x2x_2
0
1

𝔻′\mathbb{D}'

R′R' x1x_1 x2x_2
0 0
0 1
2 1
S′S' x1x_1 x3x_3
0 0
2 0
T′T' x2x_2 x3x_3
0 0
1 0

Branch and bound complexity

|Qi(𝔻)|≤wc(Q,N) |Q_i(\mathbb{D})| \leq wc(Q,N)

The complexity of the branch and bound algorithm is

Õ(m|𝖽𝗈𝗆|⋅∑i=1n|Qi(𝔻)|)\tilde{O}(m|\mathsf{dom}|\cdot \sum_{i=1}^n|Q_i(\mathbb{D})|)

Õ(m|𝖽𝗈𝗆|⋅n𝗐𝖼(Q,N))\tilde{O}(m|\mathsf{dom}| \cdot n\mathsf{wc}(Q, N))

Õ(mn⋅|𝖽𝗈𝗆|⋅𝗐𝖼(Q,N))\tilde{O}(mn \cdot |\mathsf{dom}| \cdot \mathsf{wc}(Q, N))

Õ(mn⋅\tilde{O}(mn \cdot|𝖽𝗈𝗆|{|\mathsf{dom}|}⋅𝗐𝖼(Q,N))\cdot \mathsf{wc}(Q, N))

We do not even need to know 𝗐𝖼(Q,N)\mathsf{wc}(Q,N) to prove it!

Make the domain binary!

RR xx yy
1 2
2 1
3 0

⇝

R̃b\tilde{R}^b x2x^2 x1x^1 x0x^0 y2y^2 y1y^1 y0y^0
0 0 1 0 1 0
0 1 0 0 0 1
0 1 1 0 0 0

WCOJ finally

We hence compute Q(𝔻)Q(\mathbb{D}) in time Õ(mn⋅𝗐𝖼(Q,N))\tilde{O}(m n \cdot \mathsf{wc}(Q, N))!

More on Binarization

Worst case and functional dependencies

Functional dependencies

Q=R(x1,x2)∧S(x2,x3)Q = R(x_1,x_2) \wedge S(x_2,x_3).

We have: 𝗐𝖼(Q,N)=N2\mathsf{wc}(Q,N) = N^2.

What if we know that every database verify a key constraint x2→x1x_2 \rightarrow x_1?

(ie fixing the value of x2x_2 fixes the value of x1x_1).

The worst case is NN on such database!

Worst-case and constraints

𝗐𝖼(Q,N)\mathsf{wc}(Q,N):

𝗐𝖼(Q,N,x→y,z→w…)\mathsf{wc}(Q,N,x\rightarrow y, z \rightarrow w \dots)

𝗐𝖼(Q,𝒞)\mathsf{wc}(Q,\mathcal{C}):

Back to the example

Q=R(x1,x2)∧S(x2,x3)Q = R(x_1,x_2) \wedge S(x_2,x_3).

We have:

Is our algorithm worst-case optimal for this class?

Yes if x2x_2 is set before x1x_1: UNIT PROPAGATION!

More than one FD

Σ\Sigma is a directed graph: strong connected components induce a preorder ≺\prec on variables.

“DPLL is worst-case optimal”!

Wrap up

How far can we push this and remain worst case optimal?

Les slides auxquelles vous avez échappé

Uniform Sampling of answers

Given QQ and 𝔻\mathbb{D}, sample τ∈Q(𝔻)\tau \in Q(\mathbb{D}) with probability 1|Q(𝔻)|\frac{1}{|Q(\mathbb{D})|} or fail if Q(𝔻)=∅Q(\mathbb{D}) = \emptyset.

Naive algorithm by materialization: Õ(𝗐𝖼(Q,N)poly(|Q|))\tilde{O}(\mathsf{wc}(Q,N) poly(|Q|)).

Algorithm by randomly navigating the tree: Õ(𝗐𝖼(Q,N)|Q(𝔻)|+1poly(|Q|))\tilde{O}(\frac{\mathsf{wc}(Q,N)}{|Q(\mathbb{D})|+1} poly(|Q|)).

Degree Constraints

A degree constraint is a constraint (X,Y,NY|X)(X,Y,N_{Y|X}) where X⊆YX \subseteq Y. A relation RR verifies the constraint if

max⁡{|∏YR[τ]|,τ∈𝖽𝗈𝗆X}≤NY|X \max \{ |\prod_{Y} R[\tau]|, \tau \in \mathsf{dom}^X\} \leq N_{Y|X}

  • Cardinality constraint = degree constraint with X=∅X = \emptyset.
  • Functional dependency = degree constraint with NY|X=1N_{Y|X} = 1.

Acyclic Degree Constraints

Δ={(X1,Y1,N1)…,(Xk,Yk,Nk)}\Delta = \{(X_1, Y_1, N_{1}) \dots, (X_k, Y_k, N_k)\} set of degree constraints.

  • G(Δ)G(\Delta): vertices are the variables and x→yx \rightarrow y if x∈Xix \in X_i and y∈Yiy \in Y_i for some ii.
  • If G(Δ)G(\Delta) is acyclic, then let π=x1,…,xn\pi = x_1,\dots,x_n be a topological sort of G(Δ)G(\Delta). Then

Our algorithm is worst case optimal wrt Δ\Delta (as long as we follow π\pi).