The Fastest Computation Is the One Your Dependencies Let You Avoid

Kai Nguyen

Hatched by Kai Nguyen

Aug 16, 2026

12 min read

92%

0

What if the fastest way to answer a question is not to calculate faster, but to ask it in an order that makes most calculations unnecessary?

That principle appears in two places that seem unrelated. In databases, a query becomes fast when the system can use indexes, filter rows early, avoid needless sorting, and postpone expensive work until it knows that work is necessary. In dependency graphs, a solution becomes possible when tasks are arranged according to their prerequisites, beginning with nodes that have no incoming dependencies and ending with nodes that depend on everything before them.

One is about retrieving data. The other is about ordering tasks. But both expose the same deeper truth:

Efficiency is often less about doing each operation quickly than about arranging operations so that expensive work happens late, rarely, or not at all.

This is a general theory of intelligent execution. It applies to SQL, software architecture, project planning, scientific research, and even personal decision making. The central question is not simply, “What steps are required?” It is, “What must be true before each step becomes worth performing?”

The hidden structure of a simple request

Consider a request from an online store: find the ten most expensive winter jackets currently in stock, rated above four stars, and return them ordered by price.

A human might imagine the task as one smooth action: search for jackets, filter them, sort the results, and take the first ten. A database engine sees something more precise. It must identify records, apply conditions, combine information if several tables are involved, arrange rows, and reduce the final output.

The order matters enormously. If the system sorts ten million products before discovering that only 2,000 are winter jackets, it has performed a costly operation on an unnecessarily large set. If it can use an index to locate relevant products first, then the later steps operate on a much smaller population.

This resembles a dependency graph. Sorting depends on knowing which rows qualify. Returning the top ten depends on sorting, or on using an alternative structure that can identify the top values. Each operation has prerequisites, and some operations generate information that makes later operations cheaper.

A useful way to model the query is as a directed graph:

  1. Locate candidate records.
  2. Apply selective filters.
  3. Join related data if necessary.
  4. Rank or sort the survivors.
  5. Return only the requested rows.

This is not merely a sequence of commands. It is a partial order of obligations. Certain steps can be rearranged safely, while others cannot. Filtering might happen before a join in some cases, but ranking cannot meaningfully happen before the relevant candidates are known. The database optimizer is therefore solving a problem that is structurally similar to topological sorting: find an execution order that respects dependencies while minimizing cost.

The important insight is that a good execution plan is not just valid. Many plans can produce the same answer. The valuable one is the plan that respects the dependency constraints and reduces the size and cost of subsequent work as early as possible.

Sources, sinks, and the economics of information

In a dependency graph, a source is a node with no incoming edges. It can be processed immediately because nothing else must happen first. A sink is a node with no outgoing edges. It represents an endpoint, often a final deliverable or result.

These concepts offer a powerful lens for query design.

A raw indexed lookup is often close to a source. It requires little prior computation and can quickly identify a subset of records. A final projection or limited result set is close to a sink. It should happen after the system has enough information to know what belongs in the answer.

Between them are transformations with different costs. Some reduce the candidate set. Others expand it. Some preserve useful structure. Others destroy it by calculating a new value for every row or by sorting a large intermediate result.

This suggests a basic rule for efficient systems:

Move operations that reduce uncertainty toward the beginning, and move operations that amplify cost toward the end.

Suppose a table contains ten million user events, but only 500 belong to a particular account on a particular day. A filter that uses an index can reduce the working set immediately. A function applied to every timestamp may prevent the index from being used, forcing the database to inspect far more rows than necessary.

For example, a condition such as:

WHERE event_time >= '2026-08-15 00:00:00'
  AND event_time < '2026-08-16 00:00:00'

usually gives the database a searchable range. By contrast, a condition such as:

WHERE DATE(event_time) = '2026-08-15'

may require calculating DATE(event_time) across many rows before deciding which records qualify. The two expressions describe the same logical intention, but they present very different execution possibilities.

The first exposes the structure of the search to the engine. The second hides it inside a calculation.

That is what SARGABLE means in practice. A SARGABLE condition is shaped so that the database can search an index directly rather than transforming each stored value first. It preserves the path from a question to a searchable region of the data.

The analogy to dependency resolution is exact enough to be useful. If a task is expressed in a way that conceals its prerequisites, the scheduler cannot place it efficiently. If a query condition is expressed in a way that conceals the indexed search boundary, the database cannot exploit its existing structure efficiently.

The cost of hiding the graph

Poor query performance often comes from hiding relationships that the system needs in order to choose a good plan.

An arithmetic operation on an indexed column can obscure the range that the index represents. Negation can make the qualifying set difficult to locate directly. A leading wildcard, as in LIKE '%phone', gives the engine no known starting point in the indexed text. A function wrapped around a column may force row by row evaluation instead of allowing a direct search.

These are not arbitrary style rules. They are examples of a broader failure mode: the query has concealed the topology of its own execution.

Imagine a construction project where every task is described as “do this whenever it seems relevant,” without stating which tasks depend on which materials or approvals. The workers may eventually finish, but they cannot identify the safe starting points. They will repeatedly check blocked tasks, move materials unnecessarily, and discover dependencies late.

A database facing a poorly expressed query behaves similarly. It may still return the correct answer, but it has fewer opportunities to begin with selective, cheap operations. It must inspect, calculate, or sort more broadly because the query has hidden the conditions under which work can be safely eliminated.

This gives us a practical distinction between two kinds of complexity:

Computational complexity is the amount of work required by the task itself.

Structural complexity is the difficulty of discovering which work is necessary, in what order, and under which conditions.

Developers often focus on the first. They ask whether a sort is efficient, whether a loop is optimized, or whether a query uses an index. But the second question is often more important: can the system see enough structure to avoid the operation altogether?

A fast sorting algorithm is still wasteful if sorting was unnecessary. A highly optimized calculation is still expensive if an early filter could have removed ninety nine percent of the inputs.

The shrinking frontier: a general model for efficient execution

We can turn this into a mental model called the shrinking frontier.

At any point in a computation, there is a frontier between what the system knows and what it has not yet processed. Good execution moves that frontier forward while shrinking the set of possibilities. Bad execution moves it forward while preserving or expanding a large set of possibilities.

In a database query, the frontier shrinks when a selective indexed condition reduces millions of rows to thousands. It expands when a join duplicates records, when a broad wildcard matches a large portion of a table, or when a calculation creates a new value for every candidate row.

In a dependency graph, the frontier shrinks when completing one source node unlocks a small, well defined group of dependent tasks. It becomes difficult when many nodes remain blocked because prerequisites were not identified clearly or because a cycle prevents any node from becoming available.

The shrinking frontier yields four questions for any workflow:

  1. What can be known immediately? These are the source operations.
  2. Which early facts eliminate the most possibilities? These are the highest value filters.
  3. Which operations increase the amount of material to process? These should be delayed or carefully constrained.
  4. What final work is only useful after the candidate set is small? These are often ranking, formatting, aggregation, or presentation steps.

Consider a hiring pipeline. A company might review every application in detail, then check whether candidates have the required work authorization, then schedule interviews. That is equivalent to sorting a huge table before applying a selective filter. A better design uses cheap, decisive conditions early, reserving expensive human evaluation for the smaller set that survives.

Or consider a research project. Instead of reading every paper in a field, a researcher can define the question, identify inclusion criteria, remove irrelevant domains, and then perform deep analysis on the remaining studies. The goal is not to read faster. It is to reduce the number of papers that deserve to be read at all.

The same pattern appears in incident response, customer support, fraud detection, and compiler design. Efficient systems repeatedly ask: what is the cheapest observation that will eliminate the largest amount of future work?

Why limiting the answer changes the whole problem

One of the most underestimated optimization techniques is limiting the result set.

If a user asks for the ten newest records, returning ten million records and allowing the application to discard the rest is not merely inefficient. It misunderstands the shape of the request. The desired result is small, so the execution plan should preserve that smallness throughout the process wherever possible.

Limiting output also changes which algorithms are attractive. A full sort of every qualifying row may be unnecessary if the system can maintain a smaller structure containing only the best ten candidates. The request for a small answer creates an opportunity to prevent intermediate results from becoming large.

This is another connection to topological execution. A sink does not need every possible intermediate artifact. It needs only the information required to produce the final result. If the final node asks for ten items, the upstream plan should avoid manufacturing millions of fully processed items unless correctness demands it.

There is a subtle design lesson here: requirements should express their narrowness as early as possible. “Give me everything, and I will choose later” transfers cost downstream. “Give me the best ten according to this rule” gives the entire system permission to optimize around a constrained target.

The same principle applies outside databases. A manager who asks for a complete analysis when a decision needs only three scenarios creates unnecessary work. A monitoring system that stores every detail forever may make important signals harder to detect. A meeting that includes everyone who might possibly care delays the people who actually need to decide.

Precision is not only a communication virtue. It is a computational resource.

A practical method: design the order before the operation

Before writing a complex query or workflow, map the dependencies explicitly. Write down the final answer, then work backward.

If the result must contain the ten most expensive qualifying products, ask what must be true before each stage:

  • The product must satisfy the category condition.
  • It must satisfy the inventory condition.
  • It must satisfy the rating condition.
  • Only then is it a candidate for ranking.
  • Only after ranking is it necessary to return the top ten.

Next, classify each condition by how directly it can use existing structure. Can an index locate it? Does it require a function or calculation? Does it broaden the result set? Does it involve a join that could be postponed until after a selective filter?

Then inspect the execution plan rather than trusting the query’s visual simplicity. A short query can produce a long and expensive plan. A slightly more explicit query can reveal the boundaries that allow efficient access.

For general workflows, use the same procedure:

  1. Define the smallest useful output.
  2. List every prerequisite for producing it.
  3. Identify the source tasks that can begin without waiting.
  4. Find the earliest tests that eliminate the most work.
  5. Delay sorting, formatting, aggregation, and other expensive transformations.
  6. Check for cycles, redundant steps, and operations that destroy useful structure.
  7. Measure the actual plan and revise the ordering.

This method does not mean every filter must always move as early as possible. Semantics matter. A filter cannot be pushed ahead of a transformation if doing so changes the meaning of the query. A task cannot be processed before its true prerequisites are complete. Optimization is constrained rearrangement, not careless rearrangement.

The art lies in distinguishing operations that are logically dependent from operations that are merely written in a particular order. Once that distinction is clear, many improvements become available.

Key Takeaways

  • Expose searchable structure. Write conditions so the system can use indexes directly. Avoid wrapping indexed columns in unnecessary calculations, especially in filtering conditions.
  • Filter before you amplify. Reduce the candidate set before joins, sorting, grouping, enrichment, or expensive calculations whenever the logic allows it.
  • Treat dependencies as a graph. Identify source operations, prerequisite relationships, blocked tasks, and final sinks before deciding on an execution order.
  • Make the desired output narrow. Use limits, precise requirements, and selective criteria to prevent small answers from requiring enormous intermediate work.
  • Measure the plan, not the intention. Inspect actual execution behavior. The shortest query or workflow is not necessarily the cheapest one.

The most consequential optimization is often invisible in the final result. The user sees ten products, receives a report, or gets a decision. They do not see the millions of rows never scanned, the tasks never started, or the calculations never performed.

That invisible absence is the signature of a well designed system.

We often imagine intelligence as the ability to solve difficult problems through greater effort. In practice, intelligence is just as often the ability to recognize which effort is premature. A database becomes faster when its question preserves the paths its indexes can search. A project becomes faster when its dependencies reveal what can begin and what must wait. Both succeed by making the structure of necessity visible.

So the next time a query, project, or decision feels slow, do not begin by asking how to accelerate every step. Ask a more disruptive question: which steps should never have been taken, and what ordering would have revealed that sooner?

Sources

← Back to Library

Hatch New Ideas with Glasp AI 🐣

Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)

Start Hatching 🐣
The Fastest Computation Is the One Your Dependencies Let You Avoid | Glasp