SQL Query Lifecycle: From SQL Text to Results

SQL Query Lifecycle Canvas

SQL Query Lifecycle --- Quick Canvas

Before going into the details, here is the whole lifecycle with the input and output of every phase:

┌───────────────────────────────────────────────────────────────┐
│ 1. PARSER                                                     │
│ Input:  SQL text                                              │
│        SELECT name FROM employees WHERE salary > 10000;       │
│                                                               │
│ Does:   Tokenization + syntax checking                        │
│ Output: Parse Tree / AST                                      │
└──────────────────────────────┬────────────────────────────────┘
                               ▼
┌───────────────────────────────────────────────────────────────┐
│ 2. ANALYZER                                                   │
│ Input:  Parse Tree / AST + Database Catalog                   │
│                                                               │
│ Does:   Semantic checks                                       │
│         - Do tables/columns exist?                            │
│         - Are types/references valid?                         │
│ Output: Analyzed query / Logical Query Plan                   │
└──────────────────────────────┬────────────────────────────────┘
                               ▼
┌───────────────────────────────────────────────────────────────┐
│ 3. QUERY OPTIMIZER                                            │
│ Input:  Logical Query Plan + Statistics + Catalog metadata    │
│                                                               │
│ Does:   Generate alternatives + apply rules + estimate costs  │
│         - Join order                                          │
│         - Scan method                                         │
│         - Join algorithm                                      │
│         - Aggregation / sorting strategy                      │
│ Output: Final Physical Execution Plan                         │
└──────────────────────────────┬────────────────────────────────┘
                               ▼
┌───────────────────────────────────────────────────────────────┐
│ 4. EXECUTION ENGINE                                           │
│ Input:  Physical Execution Plan                              │
│                                                               │
│ Does:   Execute physical operators                            │
│         Scan → Filter → Join → Aggregate → Sort ...           │
│ Output: Rows / Query Result                                   │
└──────────────────────────────┬────────────────────────────────┘
                               ▼
                         ┌──────────┐
                         │  RESULT  │
                         └──────────┘

Lifecycle in one table


Phase Input Main Job Output


Parser SQL text Tokenize and Parse Tree / AST check syntax

Analyzer Parse Tree + Check meaning, Analyzed / Catalog objects and types Logical Plan

Optimizer Logical Plan + Find a good way Physical statistics to execute it Execution Plan

Execution Physical Plan Run the selected Query Result Engine operators

SQL tells the database WHAT you want. The optimizer and execution engine decide HOW to get it.


1. Parser

The first component that receives our SQL is the Parser.

Its job is to understand the structure of the SQL statement.

For example:

SELECT name
FROM employees
WHERE salary > 10000;

The parser first breaks the SQL into tokens.

Token type Examples


Keywords SELECT, FROM, WHERE, UPDATE Identifiers employees, name, salary Operators >, <, =, +, - Constants 10000, 'Amr' Symbols (, ), ,

Then it performs syntax checking.

For example:

SELECT FROM employees;

is syntactically invalid.

The parser normally produces a structure called a Parse Tree or Abstract Syntax Tree (AST) representing the SQL statement.

SQL
 │
 ▼
Tokenization
 │
 ▼
Syntax Checking
 │
 ▼
Parse Tree / AST

At this point, however, the database still hasn't verified that things such as employees or salary actually exist.

That's the next stage.


2. Analyzer

The Analyzer performs semantic analysis.

The parser asks:

"Is this valid SQL syntax?"

The analyzer asks:

"Does this SQL actually make sense inside this database?"

For example:

SELECT salary
FROM employees;

The analyzer checks things such as:

  • Does the employees table exist?
  • Does the salary column exist?
  • Is the column accessible?
  • Are the types compatible?
  • Which schema/table does an identifier refer to?

To answer these questions, the analyzer uses the database Catalog.

The Catalog

The catalog is essentially a collection of database metadata.

It contains information about database objects rather than the actual application data.

For example:

Catalog
 ├── Schemas
 ├── Tables
 ├── Columns
 ├── Data Types
 ├── Indexes
 ├── Constraints
 └── Statistics

In PostgreSQL, for example, system catalogs include objects such as:

pg_namespace
pg_class
pg_attribute
pg_type

The analyzer uses this metadata to understand what the query references.


3. Logical Query Plan

After parsing and semantic analysis, the database can represent the query as a logical plan.

A logical plan describes what operations must happen, without deciding exactly how those operations will be implemented.

Consider:

SELECT department, COUNT(*)
FROM employees
WHERE salary > 10000
GROUP BY department;

A simplified logical plan might look like:

Aggregation
    │
Selection
    │
Table Scan

These operations are commonly represented using concepts from relational algebra.

Typical logical operators include:

Logical operation Meaning


Scan Read a relation/table Selection Filter rows Projection Select columns Join Combine relations Aggregation Calculate grouped values Sort Order results

The important point is that the logical plan still doesn't necessarily say how each operation will be executed.


4. Logical vs Physical Operators

This distinction becomes very important during optimization.

Logical Operator Possible Physical Implementation


Scan Sequential Scan Scan Index Scan Join Nested Loop Join Join Hash Join Join Merge Join Aggregation Hash Aggregate Aggregation Sort Aggregate

For example, logically we may simply need:

JOIN employees departments

But physically the database might choose:

Hash Join

or:

Nested Loop Join

So:

Logical plan = what operations are required.

Physical plan = exactly how those operations will run.


5. Query Optimizer

There are often many different ways to execute exactly the same SQL query.

Suppose we have:

SELECT *
FROM orders o
JOIN customers c
    ON o.customer_id = c.id
WHERE c.country = 'Egypt';

The database could:

Scan Customers
→ Filter Egypt
→ Join Orders

or:

Scan Orders
→ Join Customers
→ Filter Egypt

It could also choose different indexes and different join algorithms.

All of these could produce the same result, but their performance can be dramatically different.

The Query Optimizer tries to choose a good execution plan.


6. Plan Enumeration

The optimizer generates or considers alternative plans.

This process is often called plan enumeration.

Internally, alternatives can be represented using structures such as trees, DAGs, memo structures, or equivalent optimizer representations depending on the DBMS.

Conceptually:

                  Query
                    │
          ┌─────────┴─────────┐
          │                   │
       Plan A              Plan B
          │                   │
    Hash Join          Nested Loop
          │                   │
     Seq Scan            Index Scan

The number of possible plans can become enormous.

As the number of joined tables increases, the possible join orders increase very quickly.

Therefore, optimizers normally cannot blindly try every possible execution strategy for complex queries.

They use optimization rules, search strategies, statistics, and cost estimates to reduce the search space.


7. Rule-Based Optimization

Some optimizations are based on transformations that are generally beneficial.

This is rule-based optimization.

A classic example is predicate pushdown.

Instead of joining a huge number of rows and filtering afterward, the optimizer tries to apply a filter as early as possible when it is valid to do so.

Other common rules include:

  • Predicate pushdown
  • Projection pushdown
  • Expression simplification
  • Constant folding
  • Empty subtree elimination

For example:

WHERE age > 25 AND 5 > 2

Since 5 > 2 is always true, the expression can potentially be simplified.


8. Cost-Based Optimization

Rules alone aren't enough.

Sometimes there is no universally correct choice.

For example:

Sequential Scan
        VS
Index Scan

Which one is better?

It depends.

If we need most of a table, a sequential scan might be faster. If we need only a tiny fraction of the rows, an index scan might be dramatically faster.

This is where Cost-Based Optimization (CBO) comes in.

The optimizer estimates the cost of different plans and tries to choose a low-cost plan.

Decision Possible choices


Access path Sequential Scan / Index Scan Join algorithm Nested Loop / Hash Join / Merge Join Join order A → B → C / B → C → A / etc. Aggregation Hash / Sort-based Sorting Different sort strategies Parallelism Serial / Parallel execution


9. Statistics and the Cost Model

How does the optimizer know which plan is cheaper?

It uses statistics.

Statistics may describe things such as:

Number of rows
Value distribution
Number of distinct values
NULL frequency
Histograms
Column statistics

The optimizer feeds these estimates into its cost model.

Statistics
    │
    ▼
Cost Model
    │
    ▼
Estimated Cost of Plans
    │
    ▼
Choose a Plan

For example:

Plan A → estimated cost: 150
Plan B → estimated cost: 800
Plan C → estimated cost: 230

The optimizer would likely choose Plan A.

These numbers generally represent estimated relative execution costs, not simply milliseconds.

Bad or outdated statistics can therefore cause the optimizer to make poor decisions.


10. Bottom-Up vs Top-Down Optimization

Optimizer search strategies can broadly be thought about in different ways.


Bottom-Up Top-Down


Builds alternatives from smaller Starts from the required result pieces

Can be simpler conceptually Can use required output properties

May generate unnecessary Can focus search based on alternatives requirements

Common in dynamic-programming-style Common in more advanced optimizer approaches frameworks

A top-down optimizer can use requirements from the parent operation.

For example, if the final output must already be sorted by:

ORDER BY created_at

an execution strategy that naturally provides the required ordering may become more attractive.

The exact optimizer architecture differs significantly between database systems.


11. Final Physical Execution Plan

After optimization, the database has a physical plan describing exactly which physical operators should execute.

For example:

HashAggregate
      │
   HashJoin
   /     \
IndexScan SeqScan

At this stage, decisions such as these have already been made:

Which index?
Which scan?
Which join algorithm?
Which join order?
Which aggregation strategy?
Should parallelism be used?

Now the plan can be handed to the Execution Engine.


12. Execution Engine

The Execution Engine runs the selected physical plan.

SQL
 ↓
Parser
 ↓
Analyzer
 ↓
Logical Plan
 ↓
Optimizer
 ↓
Physical Plan
 ↓
Execution Engine
 ↓
Result

The execution engine contains implementations of physical operators such as:

  • Sequential Scan
  • Index Scan
  • Hash Join
  • Nested Loop Join
  • Sort
  • Aggregate

Different database systems use different execution models for connecting and running these operators.


13. Iterator Model

One of the classic execution models is the Iterator Model, often associated with the Volcano model.

Each operator exposes an interface conceptually similar to:

next()

or:

getNext()

The parent asks its child:

Give me the next row.

For example:

LIMIT
  │
  ▼
FILTER
  │
  ▼
SCAN

Execution can look like:

LIMIT asks FILTER for a row
FILTER asks SCAN for a row
SCAN returns one row
FILTER checks it
FILTER returns it
LIMIT receives it

Then the process repeats.

Advantages

  • Simple implementation
  • Naturally supports pipelining
  • Can produce results early
  • Can stop work early with operations such as LIMIT
  • Doesn't require the entire result to live in memory

Disadvantages

  • Many function calls
  • Row-at-a-time execution introduces overhead
  • Some operators are blocking

A hash join, for example, may need to build a hash table before it can produce results from part of the operation.


14. Vectorized / Batch Execution

Instead of returning one row per call, a vectorized engine processes batches of rows.

Iterator:

getNext()
→ 1 row


Vectorized:

getNextBatch()
→ N rows

Iterator Vectorized


One row at a time Batch of rows

More function-call overhead Fewer calls

Simple implementation More complex

Good pipelining Good pipelining

Often slower for analytical Often excellent for analytics workloads

Traditionally common in OLTP Common in analytical/vectorized engines engines

Processing a batch allows the CPU to perform the same operation over many values efficiently and can improve cache locality and CPU utilization.


15. Materialization Model

Another approach is materialization.

Instead of returning one row or one batch, an operator may compute its complete result and return or store that result.

Operator
   │
   ▼
Process Everything
   │
   ▼
Materialized Result

Iterator Vectorized Materialization


One row Batch of rows Entire intermediate result

Low memory requirement Moderate Potentially high

Many calls Fewer calls Few calls between stages

Good pipelining Good CPU efficiency Simple stage boundaries

Common general-purpose Excellent for Can be useful for model analytical processing small/intermediate results

Materialization can become expensive when intermediate results are very large.


16. Pull-Based Execution

Iterator-style execution is commonly pull-based.

The parent operator asks its child for data.

Parent
  │
  │ "Give me data"
  ▼
Child

So execution is driven from the top of the plan downward.

Result
  │ pull
Filter
  │ pull
Scan

Advantages include simplicity and natural control over how much data is requested.

A LIMIT 10, for example, can stop requesting rows after it receives enough.

A traditional pull-based iterator pipeline is usually executed synchronously within a thread unless the DBMS adds parallel execution separately.


17. Push-Based Execution

In a push-based model, operators produce data and push it toward the next operator.

Scan
 │
 │ push
 ▼
Filter
 │
 │ push
 ▼
Result

Rather than the parent repeatedly asking for the next row, the child invokes or transfers data toward its consumer.


Pull-Based Push-Based


Parent requests data Child sends data

Natural iterator model Data-driven execution

Simple control flow More complex coordination

Easy early stopping Early stopping can require explicit coordination

Often straightforward to implement Can fit parallel/dataflow architectures well

Push vs pull does not by itself determine whether execution is parallel. A database can build parallel execution mechanisms around either model.


18. Blocking vs Non-Blocking Operators

Not every operator can immediately return output.

Some operators can stream data:

Scan
Filter
Projection

These are often pipeline-friendly operators.

Other operators may need significant input before producing output.

Examples include:

Sort
Hash-table build phase
Some aggregations

These are often called blocking operators or pipeline breakers.

For example, a hash join may first need to:

Read build-side rows
       ↓
Build Hash Table
       ↓
Probe Hash Table
       ↓
Return Matches

So execution may pause at that stage until the required internal structure has been created.


19. EXPLAIN

SQL databases usually provide a way to inspect the plan selected by the optimizer.

In PostgreSQL:

EXPLAIN
SELECT *
FROM users
WHERE id = 10;

This shows the planned execution strategy without normally executing the query itself.

You might see:

Index Scan using users_pkey on users

instead of:

Seq Scan on users

This lets us see what the optimizer decided.


20. EXPLAIN ANALYZE

EXPLAIN ANALYZE goes further.

EXPLAIN ANALYZE
SELECT *
FROM users
WHERE id = 10;

The important difference is that the query is actually executed.


EXPLAIN EXPLAIN ANALYZE


Shows planned execution Executes the query

Uses optimizer estimates Shows actual runtime measurements too

Useful for understanding the chosen Useful for diagnosing performance plan

Safer for statements you don't want Must be used carefully with executed modifying queries

PostgreSQL also provides additional options such as:

EXPLAIN (ANALYZE, VERBOSE, BUFFERS)
SELECT ...;

VERBOSE exposes additional plan details, while BUFFERS can show buffer activity and is especially useful during performance investigation.


Putting Everything Together

                 SQL QUERY
                     │
                     ▼
              ┌─────────────┐
              │   Parser    │
              └─────────────┘
                     │
              Tokens + Syntax
                     │
                     ▼
              Parse Tree / AST
                     │
                     ▼
              ┌─────────────┐
              │  Analyzer   │◄──── Catalog
              └─────────────┘
                     │
             Semantic Checks
                     │
                     ▼
              Logical Plan
                     │
                     ▼
          ┌────────────────────┐
          │  Query Optimizer   │
          └────────────────────┘
             │             │
             │             │
       Rule-Based      Cost-Based
       Optimization    Optimization
             │             │
             └──────┬──────┘
                    │
             Plan Enumeration
                    │
               Statistics
                    │
               Cost Model
                    │
                    ▼
          Physical Execution Plan
                    │
                    ▼
          ┌──────────────────┐
          │ Execution Engine │
          └──────────────────┘
                    │
        Iterator / Vectorized /
          Push / Pull / etc.
                    │
                    ▼
                  RESULT

The Core Mental Model

SQL says WHAT you want.

Parser understands the SQL.

Analyzer checks WHAT the SQL refers to.

Logical Plan describes WHAT operations are needed.

Optimizer decides HOW to perform them efficiently.

Physical Plan describes HOW they will actually run.

Execution Engine runs that plan.

Result comes back to you.

That separation between WHAT and HOW is one of the most important ideas behind relational databases.