Expert guide
Access 'Query Is Too Complex' Error: Causes and Fixes
Rewrite the parts that exceed the engine's limits, and the query usually gets faster too
Call us at +1 (385) 386-3860
Short answer: the Access engine refuses queries whose internal plan is too large. The usual culprits are long nested IIf chains, dozens of OR conditions, big UNION queries, many joins and very long SQL. Replace IIf chains with a lookup table join (or Switch), replace OR lists with IN or a criteria table, build results in stages with saved queries, and push heavy work to SQL Server views if the data lives there. Our Access optimisation work often starts with these rewrites.
"Query is too complex" usually appears in a database that has grown organically: a commission rule added here, a new region there, until one query carries years of business logic in a single SQL statement. Access has no setting to raise the limit. The fix is to restructure the query, which almost always makes it easier to maintain as well.
Cause 1: Nested IIf Chains
The problem:
Tier: IIf([Sales]<1000,"Bronze",IIf([Sales]<5000,"Silver",IIf([Sales]<10000,"Gold",
IIf([Sales]<25000,"Platinum",IIf([Sales]<50000,"Diamond","Elite")))))
... repeated for 12 regions with different thresholdsFix A: a lookup table (best)
tblTiers: Region | MinSales | MaxSales | Tier SELECT s.*, t.Tier FROM tblSales AS s INNER JOIN tblTiers AS t ON s.Region = t.Region AND s.Sales >= t.MinSales AND s.Sales < t.MaxSales;
This is a non-equi join: it cannot be shown in the query design grid, only in SQL view, but Access runs it fine. The business can now change thresholds in a table instead of a developer editing SQL.
Fix B: Switch for a moderate list
Tier: Switch([Sales]<1000,"Bronze", [Sales]<5000,"Silver",
[Sales]<10000,"Gold", True,"Elite")Fix C: a VBA function for genuinely complex rules
Public Function GetTier(ByVal region As String, ByVal sales As Currency) As String
Select Case region
Case "North", "East": GetTier = IIf(sales >= 20000, "Gold", "Silver")
Case Else: GetTier = IIf(sales >= 15000, "Gold", "Silver")
End Select
End Function
In the query: Tier: GetTier([Region], [Sales])VBA functions in queries are slower on large tables and do not work in pass-through queries or on SQL Server, so prefer the lookup table where possible.
Cause 2: Long OR Lists
Instead of:
WHERE [ProductCode]="A12" OR [ProductCode]="B44" OR ... (60 more)
Use IN:
WHERE [ProductCode] In ("A12","B44","C07", ...)
Or a criteria table:
WHERE [ProductCode] In (SELECT Code FROM tblSelectedProducts)Forms with many check boxes that build OR conditions should write the selected values into a temporary criteria table and join to it.
Cause 3: Big UNION Queries
A UNION of many monthly or branch tables usually means data is split into tables that should be one table with a Month or Branch column. Consolidating them removes the need for the union.
If you must union, use UNION ALL (no duplicate removal) and build it in two or three smaller saved unions combined at the end.
Alternatively, append each part into a temporary table, then query that table.
Cause 4: Too Much in One Query
Build the result in stages. Stage one filters and joins the core tables, stage two adds calculations, stage three aggregates. Each saved query is simple; the final query uses the previous one as its source.
| Stage | Saved query | Does |
|---|---|---|
| 1 | qryOrders_Base | Join orders, lines, customers; filter by date range |
| 2 | qryOrders_Calc | Add margin, tier (via lookup join), flags |
| 3 | qryOrders_Summary | Group by region and month for the report |
Cause 5: Updates on Tables With Many Validations or Indexes
An UPDATE that sets many fields at once on a table with many indexes, validation rules or multivalued fields can also raise the error. Split it into two or three updates of fewer fields, or update through a recordset in VBA.
When the Data Is on SQL Server
If tables are linked from SQL Server, rewrite heavy queries as server views or pass-through queries. They run entirely on the server, avoid Access's limits and return far less data over the network. The translation approach is in AI-assisted Access to SQL Server migration.
Use AI to Untangle a Monster Query
Prompt: This Microsoft Access query returns "Query is too complex". Rewrite it as (1) a lookup table design replacing the nested IIf, (2) a set of 2–3 saved queries that build the same result in stages, and (3) the SQL for each, using Access SQL syntax. Keep column names identical so the report still works. [paste SQL]
See using ChatGPT to write Access SQL for prompting tips, and test the rewrite against the old results before replacing anything. If the query feeds a report that is also slow, the reports and forms service covers redesigning both.
FAQ
Query too complex FAQ
IIf, OR, UNION and engine limits