Hello! Welcome to the first lesson in our module on Query Optimization.
In the previous module, we mastered the "how" of query execution. You learned to implement various physical operators like scans, sorts, and joins, and you analyzed the performance trade-offs between them. But a crucial question remains: given a declarative SQL query, how does the database system decide which of these operators to use and in what order?
This lesson begins to answer that question. Your learning outcome is to translate SQL queries into relational algebra expressions for systematic optimization. We'll explore how a DBMS converts a high-level, declarative SQL statement into a procedural "logical plan" represented by relational algebra. This translation is the foundational step that allows the query optimizer to analyze, transform, and ultimately find an efficient execution strategy.
From SQL to a Logical Plan
A SQL query describes the what (the desired result), not the how (the steps to get it). The database's first job is to parse this query into a more structured, procedural format that it can work with. This process typically involves a few stages:
- SQL Query: The raw text from the application.
- Abstract Syntax Tree (AST): The parser turns the text into a tree structure representing the query's components.
- Logical Plan: The AST is converted into an initial plan using relational algebra operators. This plan is "logical" because it defines the sequence of operations but not the specific algorithm for each (e.g., it says "join," not "hash join").
- Physical Plan: The optimizer transforms the logical plan and annotates it with specific algorithms, creating a physical plan that the execution engine can run.
A high-level overview of the query processing pipeline in a DBMS. Our focus today is on the creation of the logical plan.
At its core, a logical plan is an expression in relational algebra, which we can visualize as a tree. The leaves of the tree are the tables, and data flows up from the leaves through a series of operators until the final result is produced at the root.
Here are a few basic examples of this translation:

To get a better sense of this process in action, let's watch the beginning of a lecture from CMU's database course.
F2023 #14 - Query Planning & Optimization (CMU Intro to Database Systems)
Professor Andy Pavlo provides an excellent overview of the query optimization process, starting with a simple SQL query and showing how it maps to an initial, unoptimized logical plan. This will demonstrate why this translation is so crucial for performance.
Watch the segment from 01:26 to 11:51. Focus on two key things: How the initial SQL query is translated into a logical plan tree with a Cartesian product (×), selections (σ), and a projection (π). The process of estimating the I/O cost of this naive plan and realizing how astronomically high it is. This motivates the entire field of query optimization.
The Canonical Translation of SELECT-FROM-WHERE
As you saw in the video, the most direct, or "canonical," way to translate a simple SELECT-FROM-WHERE query follows a standard recipe. This process forms the initial logical plan that the optimizer will then improve.
For a query of the form:
SELECT attribute_list
FROM R1, R2, ...
WHERE condition;
The canonical translation into relational algebra is:
This corresponds to a tree with three levels of operators:
- Cartesian Products (
×): At the bottom, all tables in theFROMclause are combined using Cartesian products. - Selection (
σ): In the middle, theWHEREclause condition is applied as a filter. - Projection (
π): At the top, theSELECTlist is used to discard unwanted columns.
Let's ground this with a formal, written explanation.
Translating SQL into the Relational Algebra
This document, 'Translating SQL into the Relational Algebra', provides a systematic guide. We will start with the simplest case.
Please read Section 2, 'Select-from-where statements without subqueries'. This section formalizes the translation process we just described and provides a concrete example.
This canonical translation is conceptually simple but, as the video highlighted, operationally very inefficient. No modern database would actually execute a large Cartesian product if it could be avoided. This initial translation is merely a starting point.
From Canonical Plan to Optimized Logical Plan
The real power of translating SQL to relational algebra is that it gives the optimizer a mathematical structure that can be transformed using a set of equivalence rules. The optimizer's first job is to apply these rules to convert the naive canonical plan into a more efficient logical plan.
The most important initial transformation is to replace Cartesian products followed by selections with joins.

Let's watch how these transformations are applied to improve our initial plan.
Database Systems: Query Optimization (Part 1), rule- vs cost-based, join graph, interesting orders
This video from Prof. Dr. Jens Dittrich's course clearly illustrates the step-by-step process of rewriting the canonical plan into a better logical plan.
Watch the segment from 07:55 to 14:15. This section demonstrates several key rule-based rewrites: Splitting predicates: Breaking a complex WHERE clause into smaller parts. Predicate Pushdown: Moving a selection (filter) down the tree to reduce data size as early as possible. Combining Cross Product and Selection into a Join: The most critical optimization for this stage.
These rewrites—pushing down selections and projections, and converting products to joins—are heuristic rules that almost always result in a better plan by reducing the size of intermediate results flowing up the operator tree.
Test your understanding!
Consider the following SQL query, which finds the names of employees who work in the 'Toy' department.
SELECT E.ename
FROM Emp E, Dept D
WHERE E.did = D.did AND D.dname = 'Toy';
- Draw (or describe) the canonical relational algebra tree for this query.
- Draw (or describe) a more optimized logical plan after applying transformations like predicate pushdown and converting the cross product to a join.
Show answer
-
Canonical Tree:
- Root: Projection
π_ename - Middle: Selection
σ_(E.did=D.did AND D.dname='Toy') - Leaves: Cartesian Product
Emp × Dept
- Root: Projection
-
Optimized Logical Plan Tree:
- Root: Projection
π_ename - Middle: Join
⋈_(E.did=D.did) - Left Leaf: The
Emptable. - Right Leaf: A selection
σ_(D.dname='Toy')applied directly to theDepttable.
This optimized plan is much more efficient because the selection on
Deptis performed first, drastically reducing the number of tuples that need to be considered in the join. - Root: Projection
Handling More Complex SQL Constructs
Real-world SQL includes more than just simple SELECT-FROM-WHERE blocks. The translation process must also handle JOIN syntax, subqueries, GROUP BY, and set operations. While the details can get complex, the principle remains the same: convert the SQL construct into an equivalent relational algebra operator or expression.
Let's briefly survey how this is done by looking at the relevant sections of the reference document. You don't need to memorize every rule, but you should understand that a corresponding algebraic construct exists for each SQL feature.
Translating SQL into the Relational Algebra
We will now quickly go through how more advanced SQL features are translated. The goal is to get a broad overview of the techniques involved.
Skim through the following sections to get a sense of the translation process for each feature: Section 6.1 (Join operations): See how explicit JOIN ON syntax translates directly to a theta-join operator, which is what we did in our optimized plan. Section 8 (Group by and Having): Notice the introduction of the γ (gamma) operator for aggregation. Section 3 (Normalizing Where-subqueries): This shows how subqueries using IN, ANY, or ALL can be rewritten into a standard form using EXISTS and NOT EXISTS. Section 5.2 & 5.3 (De-correlating subqueries): Skim these to see the introduction of the semi-join (⋉) for EXISTS and anti-join (▷) for NOT EXISTS. This is a key technique for efficiently executing subqueries without running them repeatedly.
This systematic translation for a wide range of SQL features is what makes relational algebra the lingua franca of query optimization. It provides a consistent framework for representing and manipulating any query, no matter how complex.
Conclusion
In this lesson, we've bridged the gap between declarative SQL and the procedural world of query execution. You've learned how database systems translate SQL queries into logical plans represented by relational algebra, which is the essential first step toward finding an efficient execution strategy.
Key Takeaways:
- SQL is "What," Relational Algebra is "How": Translation turns a declarative specification into a procedural plan.
- Canonical Translation: A simple
SELECT-FROM-WHEREquery can be naively translated to aProject(Select(Cross-Product))structure. This is a crucial starting point but is highly inefficient. - Relational Algebra Enables Optimization: The true purpose of this translation is to represent the query in a form where algebraic equivalence rules can be applied.
- Key Transformations: The most important initial optimizations involve replacing cross products with joins and "pushing down" selections and projections as early as possible to reduce the amount of data processed by subsequent operators.
- A Rich Toolkit: The extended relational algebra has operators (like semi-join, anti-join, and aggregation) to handle the full spectrum of SQL features, including subqueries and
GROUP BY.
Preview of the Next Lesson
We've seen that we can transform a logical plan into different, but equivalent, forms. For example, (A ⋈ B) ⋈ C is equivalent to A ⋈ (B ⋈ C). But how does the optimizer know which form is better? In our next lesson, we will focus on the rules and heuristics for this process. We will dive deeper into how to apply logical query transformations, such as predicate pushdown and join reordering, to systematically improve a query plan.