Filter operator — WHERE predicate row-by-rowMySQL 8.4 • MariaDB 11.4

Understand the internal execution loop of a Filter stage: evaluate every input row, then keep or discard.

Lesson familyFilter Operator

Parameters (filter stage)

Rows entering filter: 1000000
Rows kept by WHERE: 5.0%

Example query this animation executes

SELECT order_id, total FROM orders WHERE total > 500;

EXPLAIN Filter node behavior: child operator emits rows, then this stage evaluates WHERE total > 500 row-by-row before passing rows upward.

What you'll see in the animation

  • Left stream is child output rows entering the filter stage.
  • Middle Filter operator evaluates predicate logic for every incoming row.
  • Green rows satisfy the predicate and continue to parent operators.
  • Red rows are discarded, but CPU work already happened for them.
Ready — press Play
0.0s 0.0s

Cost readout (filter operator)

Input rows ?Rows entering the filter stage from its child operator.

—

Output rows ?Rows that satisfy the WHERE predicate and continue upward in the plan.

—

Dropped rows ?Rows evaluated but rejected by the predicate.

—

Selectivity ?Percentage of input rows that survive the predicate.

—

Rows evaluated vs rows returned (log–log)

Learn more — why filter nodes still matter

A Filter node is not always bad — it is normal in many plans. The key question is how many rows arrive at this stage.

If a selective predicate is pushed down into an index access path, far fewer rows reach this filter stage.

When you see large input rows and tiny output rows, consider adding/adjusting indexes so filtering happens earlier.