Skip to main content
After a query executes, FiQueLa wraps the results in one of two provider classes:
  • FQL\Results\Stream — a lazy generator that reads and processes rows on demand, without buffering the full result set.
  • FQL\Results\InMemory — an ArrayIterator that holds all result rows in memory at once.
Both implement the same ResultsProvider interface, so fetchAll(), fetch(), count(), and all other result methods work identically on either type.

Automatic selection

When you call $query->execute() without arguments, FiQueLa selects the result mode automatically:
Query containsResult mode
No ORDER BY, no JOINResults\Stream
ORDER BYResults\InMemory
Any JOINResults\InMemory
ORDER BY and JOINResults\InMemory
JOIN and ORDER BY always require loading data into memory. Joining builds an in-memory hash map of the right-hand table, and sorting must buffer the full result set before it can determine the correct order. Queries that use neither operation can stream results row by row.

Explicit selection

You can override the automatic choice by passing the desired class to execute():
use FQL\Results;

// Force in-memory mode
$results = $query->execute(Results\InMemory::class);

// Force stream mode
$results = $query->execute(Results\Stream::class);
Forcing Results\Stream on a query that contains ORDER BY or JOIN will not sort or join correctly — those operations depend on having all data available at once. Only force stream mode when you are certain the query does not require either.

Comparing the two modes

Results\Stream

Results\Stream is a generator-based pipeline. Rows flow through each query phase (WHERE filter, SELECT projection, HAVING filter, LIMIT) one at a time. Memory usage stays low and roughly constant regardless of file size.
use FQL\Query;

// Large file — stream mode keeps memory usage flat
$results = Query\Provider::fromFileQuery('jsonFile(events.json).events')
    ->selectAll()
    ->where('status', \FQL\Enum\Operator::EQUAL, 'active')
    ->limit(100)
    ->execute(); // Results\Stream chosen automatically

foreach ($results->getIterator() as $row) {
    // Each row is produced on demand
    process($row);
}
Stream mode also applies LIMIT early — it stops reading from the source file as soon as enough rows have been produced, which avoids scanning the entire file unnecessarily.

Results\InMemory

Results\InMemory stores all result rows in an ArrayIterator. Once populated it can be iterated any number of times without re-executing the query, and random access by offset is O(1).
use FQL\Query;
use FQL\Results;

// Force in-memory so results can be iterated multiple times
$results = Query\Provider::fromFileQuery('csv(sales.csv).*')
    ->select('region, SUM(amount)')->as('total')
    ->from('*')
    ->groupBy('region')
    ->orderBy('total')->desc()
    ->execute(Results\InMemory::class);

// First pass
foreach ($results->getIterator() as $row) {
    echo $row['region'] . ': ' . $row['total'] . PHP_EOL;
}

// Second pass — no re-execution, data already in memory
$top = $results->fetch();

Performance considerations

FactorResults\StreamResults\InMemory
Memory usageLow, constantProportional to result set size
Re-iterationRe-executes the queryFree — data already buffered
ORDER BYNot supported directlyRequired — buffers all rows to sort
JOINNot supported directlyRequired — builds hash map in memory
LIMIT without sortApplied in stream (fast)Applied after buffering
Large filesRecommendedUse with caution
For large files where you only need a filtered subset, use stream mode (the default when there is no ORDER BY or JOIN). For small result sets that you need to iterate multiple times, or any query using ORDER BY or JOIN, in-memory mode is appropriate.