Query Optimization
The Analytics Warehouse runs on ClickHouse, a columnar database. Queries behave differently than in a traditional relational database — a few habits make them dramatically faster.Key principles
1. Always filter by date
Data is physically organized by time. A date filter lets ClickHouse skip whole chunks of history without reading them — and since the warehouse now serves full history (not just 3 months), date filters matter more than ever. Each table has one primary time column to filter on:2. You don’t need to filter by company_id
Your user has a row policy that filters by your company automatically, and the data is sorted by company first — every query benefits from this without you adding anything.3. Select only the columns you need
ClickHouse reads only the columns you mention. This matters most on wide text columns (text, content, ai_automator_instructions): leaving them out of a SELECT can cut a query’s cost by an order of magnitude.
4. Aggregate in the database, not in your tool
Pull answers, not raw rows. AGROUP BY over millions of rows returns in well under a second; downloading those millions of rows into a BI tool doesn’t.
5. Use the daily rollups when they fit
fact_campaign_daily and fact_agent_daily pre-compute the most common dashboard metrics. A dashboard over a rollup reads thousands of rows instead of millions.
6. Use LIMIT when exploring
JOIN tips
- Join through ids, not names:
session_id,agent_conversation_id,hsm_id— names are for display. - Put the small table on the right side of the JOIN — ClickHouse loads the right side into memory. Dimensions are always small; joining two big fact tables works best when both sides carry a date filter.
- Include
company_idin the join key when joining facts to dimensions (as the examples in this documentation do).
System limits
Your user runs with protection limits that keep the platform stable for everyone:
If a query is cancelled by a limit:
- Add or tighten the date filter (the fix in almost every case)
- Drop unneeded columns — especially wide text columns
- Aggregate with
GROUP BYinstead of pulling raw rows - Break very large extractions into month-sized chunks (see Incremental Sync for the pattern that avoids large extractions entirely)