Relational Query Optimization Engine & AST Parser
Parses SQL declarative queries into relational algebra Abstract Syntax Trees (AST), applying rewrite transformations and generating candidate physical operator DAGs.
Measure the empirical tuple comparison counts and physical I/O costs of Relational Join Operators (Nested Loop Join, Block Nested Loop Join, Sort-Merge Join, and Hash Join) across relation cardinalities N from 1,000 to 7,000 tuples, evaluate relational algebra equivalence transformations, analyze index scan selectivity tipping points, and extract the fundamental hash join linear scaling multiplier k_join using ordinary least-squares regression. Explore interactive search algorithms, compare operation counts and analyse complexity scaling.
Ready to execute cardinality benchmark.
Adjust cardinality n, then execute benchmark.
Operation counts are generated deterministically by the exact algorithmic execution model. Modern hardware benchmarks additionally reflect cache line prefetching and branch misprediction penalties.
The simulated benchmark models an in-memory hash join with uniform key distributions and negligible bucket collision chaining, resulting in deterministic operation scaling T(N) = 2N. In physical enterprise database engines (PostgreSQL, MySQL InnoDB, Oracle, Microsoft SQL Server), execution latency is heavily modulated by: (1) external memory Grace hash partitioning and multi-pass disk I/O when relation size exceeds buffer pool capacity M; (2) data skew and duplicate join keys ('heavy hitters') creating unbalanced hash chains; (3) NUMA memory bus node remote access penalties on multi-socket database servers; (4) parallel query execution thread synchronization and exchange operator (Tuple Mover / Gather) serialization overhead; and (5) cardinality estimation errors propagating exponentially through multi-join query trees. In an in-memory equi-join between two relations R and S of identical cardinality |R| = |S| = N, the classical Hash Join algorithm operates in two sequential phases: (1) Build Phase: The optimizer designates relation R as the build input. For each of the N tuples in R, the engine evaluates the hash function on the join key h(t_R.k) and inserts the tuple into the corresponding hash bucket, performing exactly N insertion operations. (2) Probe Phase: The engine scans relation S as the probe input. For each of the N tuples in S, it computes the hash value h(t_S.k), accesses the hash bucket, and evaluates the join predicate against matching candidate keys. Under uniform hash distribution and unique primary-foreign key relationships, each probe executes exactly 1 tuple comparison, totaling N probe comparisons. The total operation count is strictly T(N) = N (build insertions) + N (probe comparisons) = 2.0000 · N operations. Ordinary least-squares linear regression against tuple cardinality N yields an empirical scaling multiplier of k_join = 2.0000 comparisons/tuple with baseline intercept T_0 = 0.0000 operations and correlation coefficient R² = 1.00000. In contrast, Nested Loop Join scales quadratically as C_nlj(N) = N², Block Nested Loop Join incurs B(R) + ⌈B(R)/(B-2)⌉ · B(S) disk block transfers, and Sort-Merge Join incurs 2 B(R) log_{B-1}(B(R)/B) + 2 B(S) log_{B-1}(B(S)/B) + B(R) + B(S) block I/Os.
Parses SQL declarative queries into relational algebra Abstract Syntax Trees (AST), applying rewrite transformations and generating candidate physical operator DAGs.
Implements Selinger dynamic programming algorithm searching left-deep join orderings, evaluating CPU and I/O cost formulas, and preserving interesting sort orders.
Executes partition hashing and bucket chaining across build and probe relations, recording atomic hash computations, bucket insertions, and key comparison operations.
Allocates B = 64 memory frames (each 4KB) with LRU replacement policy, tracking disk page block I/Os, cache hits, and dirty page writeback counts.
Maintains tree indexing over relation attributes, providing logarithmic key lookups and simulating index scan selectivity tipping points against sequential full scans.
Maintains relation metadata including cardinality |R|, page count B(R), distinct attribute values V(A, R), and equi-depth histograms for selectivity estimation.
Measure the empirical tuple comparison counts and physical I/O costs of Relational Join Operators (Nested Loop Join, Block Nested Loop Join, Sort-Merge Join, and Hash Join) across relation cardinalities N from 1,000 to 7,000 tuples, evaluate relational algebra equivalence transformations, analyze index scan selectivity tipping points, and extract the fundamental hash join linear scaling multiplier k_join using ordinary least-squares regression. Suggested independent settings: 1000, 2000, 3000, 4000, 5000, 6000, 7000 tuples.
Configure the database engine with buffer pool size B = 64 pages (4KB page size). Populate the system catalog with metadata for relations R and S across benchmark cardinalities N in [1000, 2000, 3000, 4000, 5000, 6000, 7000] tuples, setting tuple size to 80 bytes (50 tuples per 4KB page, B(R) = B(S) = N/50 pages).
Parse the declarative join query into a canonical relational algebra tree: π_{R.name, S.dept} (σ_{R.age > 30 ∧ S.budget > 50000} (R ⋈_{R.dept_id = S.id} S)). Apply heuristic optimization rules: push selections σ below joins to filter base relations early, and push projections π to prune unused columns before buffering.
Compute theoretical cost estimates for candidate physical join operators using catalog statistics: evaluate Nested Loop Join (C_nlj = N² comparisons), Block Nested Loop Join (I/O = B(R) + ⌈B(R)/(B-2)⌉ · B(S)), Sort-Merge Join (I/O = 3(B(R) + B(S))), and Hash Join (I/O = 3(B(R) + B(S)) external, or in-memory T(N) = 2N operations).
Initiate execution of the in-memory Hash Join. Designate relation R as the inner build relation. Allocate a hash table with 2N slots. For each tuple t_R in R, evaluate hash function h(t_R.dept_id), insert the tuple into the corresponding bucket, and record N build operations.
Scan outer relation S as the probe input. For each tuple t_S in S, evaluate h(t_S.id) to index into the hash table bucket. Traverse the bucket's linked chain and evaluate key equality (t_R.dept_id == t_S.id). Under uniform distribution and unique keys, execute exactly 1 key comparison per probe tuple, recording N probe comparisons.
Record total tuple comparison operations T_hash = 2N into the notebook. Repeat across all relation cardinalities N in [1000, 2000, 3000, 4000, 5000, 6000, 7000]. Plot T against N and perform ordinary least-squares regression to verify slope k_join = 2.0000 comparisons/tuple, intercept T_0 = 0.0000, and R² = 1.00000.
Points are your recorded benchmark observations. The regression line validates Relational Query Optimization complexity scaling.
| # | Relation cardinality N (tuples) (tuples) | Hash join tuple comparisons T_hash (comparisons) | Relation tuple space N (tuples) | Hash join tuple comparisons T (operations) | Remove |
|---|
No readings yet. Execute a cardinality benchmark and record it.