# Fixing a Slow Epicor BAQ (Business Activity Query)

> Source: https://netray.co/erp-help/epicor-baq-performance-slow-fix
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: ERP Help

## Short answer

A slow BAQ in Epicor is usually caused by unindexed join columns, a subquery or calculated field forcing a table scan, or the BAQ pulling far more rows than the dashboard actually displays before filtering client-side. Fix it by reading the SQL Server execution plan Epicor generates, moving filters into the BAQ criteria instead of the dashboard filter panel, and replacing subqueries with joins where possible.

## Kind

how-to

## System

epicor

## Erp

Epicor Kinetic / Epicor ERP 10

## Module

BAQ / Reporting

## Query

Epicor BAQ running slow how to fix performance

## Alternate Queries

- Epicor Business Activity Query timeout
- how to optimize a slow BAQ in Epicor
- Epicor BAQ taking too long to load dashboard
- Epicor dynamic query performance tuning

## Applies To

Epicor ERP 10.1, 10.2, Epicor Kinetic - all BAQ, BAQ Report, and Dashboard-based BAQs

## Steps

### Diagnose and tune the query

**Items:**

Open the BAQ in BAQ Designer, go to the Analyze or Execution Plan tab if available, or run the generated SQL directly in SQL Server Management Studio against the same company database.

In SSMS, turn on Include Actual Execution Plan and run the query - look for Table Scan or Index Scan operators with a high relative cost, which point to the join column or WHERE clause that needs an index.

Check every join for calculated or subquery-based fields (Sub-Query phrases in BAQ Designer) - these often run once per outer row instead of being flattened into a single set-based join, which is the single biggest cause of BAQ slowness.

Move any filter that is always applied (company, site, a date range, a status) into the BAQ's Criteria tab as a fixed or default-value filter rather than leaving it to the dashboard's runtime filter panel, so SQL Server can use it during query planning.

Check whether the BAQ selects fields from tables that are not actually joined on an indexed key - EntryPerson, LastChangedBy and similar audit columns are common offenders when pulled from a large table like OrderDtl.

For dashboards, confirm Auto Search / Auto Refresh are off if the underlying BAQ is heavy, and set a sensible row limit (Top N or a default filter) so the query does not pull the entire table before the user narrows it.

If the BAQ needs to remain complex, consider a BAQ-based Business Activity Query view materialized through a scheduled BAQ Export or a SQL indexed view, rather than recalculating on every open.

## Sections

### Where BAQ slowness actually comes from

**Body:**

BAQ Designer generates fairly literal SQL from the visual join and criteria tabs, so almost every performance problem traces back to something in the design rather than to Epicor itself: an unindexed join column, a subquery phrase that runs per row, or a calculated field that references another table inline instead of through a join.

The Epicor tables most often at fault are large transactional tables - OrderDtl, PartTran, JobOper, GLJrnDtl - where a join on a non-key column (Company plus one field instead of the full compound key) forces SQL Server into a scan of millions of rows instead of a seek.

### Subqueries vs joins

**Body:**

BAQ Designer's "Sub-Query" phrase type is convenient for pulling a single related value (last invoice date, most recent PO price) but SQL Server frequently executes it as a correlated subquery, once per outer row, rather than optimizing it into a set-based join. For anything returning more than a few hundred rows, replace the sub-query phrase with an explicit table join and a calculated field or a Top 1 with an ORDER BY, or push the logic into a SQL view the BAQ then reads from.

### Filters: BAQ criteria vs dashboard filter panel

**Body:**

A filter typed into the dashboard's runtime search panel is applied by the Epicor client after the BAQ has already returned its result set from SQL Server in many dashboard configurations, or at best as a late-bound parameter, which is less efficient than a WHERE clause SQL Server can use for an index seek during planning. Always push permanent filters (Company, a status list, a date window) into the BAQ Criteria tab as either a fixed filter or a required runtime parameter, so the generated SQL includes them from the start.

### Indexing without touching Epicor system tables directly

**Body:**

Do not add custom indexes directly to Epicor's own tables through SSMS - upgrades and Epicor's own index maintenance can drop or conflict with them, and it is unsupported. Instead, work with your Epicor partner or Epicor Support to request an index change through supported channels, or materialize the heavy query into a separate reporting table or view outside the core schema that your BAQ reads from instead.

## Pitfalls

- Adding unsupported custom indexes directly on core Epicor tables instead of going through Epicor Support or a materialized reporting layer.
- Leaving default filters in the dashboard search panel instead of the BAQ Criteria tab, which defeats SQL Server's ability to plan around them.
- Using multiple nested sub-query phrases for lookups that would be a single join with a Top 1 or MAX aggregate.
- Testing performance only in a small test company - row counts and skew in production are what actually reveal the slow plan.
- Forgetting that a BAQ used inside a BPM directive runs on every affected transaction, so a slow BAQ there is a system-wide slowdown, not just a slow report.
- Rebuilding the whole BAQ from scratch before checking the execution plan, which often finds a single missing join condition instead.

## Ai Angle

ERPray, connected read-only to the Epicor database, can answer "why is this BAQ slow" by reading the same generated SQL and execution plan a DBA would, then explaining in plain language which join or sub-query phrase is the likely cause - shortening the diagnosis step before a developer opens BAQ Designer to fix it. It does not change indexes or the BAQ itself; that stays a reviewed, deliberate change.

## Faq

### Does Epicor cache BAQ results?

**Answer:** Not by default for standard BAQs run interactively - each open or refresh re-runs the query. Some dashboard configurations and BAQ Reports scheduled through System Monitor do cache their last output, so check whether you are looking at a live query or a scheduled snapshot before assuming a slow BAQ got faster on its own.

### Can I see the actual SQL Epicor generates from a BAQ?

**Answer:** Yes - most BAQ Designer versions have an Analyze tab or a way to export/view the generated SQL, or you can capture it with SQL Server Profiler or Extended Events while running the BAQ. Running that captured SQL directly in SSMS with an execution plan is the fastest way to find the real bottleneck.

### Is a BAQ or an SSRS/BAQ Report slower for the same data?

**Answer:** The underlying query cost is usually identical since BAQ Reports run the same BAQ; the difference is rendering and pagination overhead in the report engine on top. If the BAQ itself is slow, fixing the query helps both the interactive BAQ and any report built on it.

### Should I use a calculated field or a SQL view for complex logic?

**Answer:** For logic reused across several BAQs, a SQL view (deployed through supported customization practices, not directly against core tables) is usually faster and easier to maintain than repeating the same calculated field or sub-query phrase in every BAQ that needs it.

## Search terms

Epicor BAQ slow, Epicor BAQ performance tuning, Epicor Business Activity Query timeout, Epicor dashboard slow to load, Epicor BAQ execution plan, Epicor BAQ subquery vs join, Epicor BAQ Designer optimization, Epicor SQL Server index BAQ, Epicor BAQ Report slow, Epicor BAQ criteria filter performance

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
