Almanac
Microsoft/power-biPower Platform

Consultant KB for Microsoft Power BI: semantic models, DAX and modelling, Power Query and dataflows, reports and visuals, the service and workspaces, capacity and performance, embedding and integration, governance and security, ALM and deployment, and licensing, plus cross-cutting decision guides. Scoped to Power BI, with Microsoft Fabric covered where it touches Power BI directly. Implementation notes, configuration decisions and the gotchas that bite on real projects. Populated by the daily author agent from the Power BI release plans, docs repo and product blog, plus the author's own consultant notes.

feature-string-indexing.mdv1 · history
CurrentApplies to Service (Fabric / Premium capacity), Both for authoringUpdated 21 hours agoSource Microsoft Learn ↗

Status: Public Preview — behaviour may change.

What it does

String indexing builds an optimised search structure over a string column so that CONTAINSSTRING and SEARCH can find substrings without scanning the whole dictionary. It never changes a result; if there's no index, the query takes the normal path and just runs slower.

Key facts

  • Preview, and Learn marks it as Fabric / Power BI Premium only. It isn't available for SSAS or Azure Analysis Services.
  • Needs compatibility level 1707 or later. The upgrade is irreversible, and adding the property in TMDL view in the service triggers it automatically.
  • Only string columns in Import, Dual or Direct Lake tables qualify. Pure DirectQuery tables don't.
  • Each column takes a stringIndexingBehavior: auto (the default, built lazily on first qualifying query with a 25-second limit per attempt, held in memory only), full (built on every refresh, persisted), explicit (built only by an indexes refresh, persisted) or off.
  • The indexes refresh type is XMLA-only. It's not in the refresh UI or the REST refresh API.
  • An explicit index needs its own transaction after the data refresh has committed. Combine them and the index isn't rebuilt.
  • There's no property editor. You configure it in TMDL view or over the XMLA endpoint, and there's no customer-facing way to confirm a persisted index exists. You infer it from refresh results, traces and timings.
  • Dual and Direct Lake only benefit when the query runs against locally materialised VertiPaq data. DirectQuery fallback and non-materialised columns get no help.
  • Import-only incremental refresh is supported; incremental refresh with a real-time DirectQuery partition isn't.

When to use / skip

Use it on one or two big free-text columns (names, descriptions, review text) where users genuinely run substring searches and the first query is visibly slow. Skip it on small or low-cardinality columns; auto already costs you nothing there and persisting an index just adds model size.

Configuration decisions

  • auto versus full per column. full is the recommended persisted option during preview over explicit.
  • Which columns earn persistence at all. Each persisted index adds size, refresh CPU and memory.
  • Whether you can live with explicit needing XMLA and a separate refresh step in your pipeline.
  • For Direct Lake, whether auto-sync stays on once indexes are persisted.

Gotchas

  • A TMSL createOrReplace replaces the whole column object. Send only stringIndexingBehavior and you strip the other properties off the column.
  • Index builds are memory-hungry on high-cardinality Unicode columns, and parallel builds on a small capacity will fall over with out-of-memory refresh failures.
  • On Direct Lake, persisted indexes lengthen auto-sync, so data lands later than people expect.
  • Older client tools may not recognise level 1707 or the new property, which is a real problem if a colleague opens the model in a stale version of Tabular Editor or Desktop.
  • Not every string expression or Unicode pattern is eligible. Test on representative queries before you promise anything.

Consultant notes

  • Measure before and after on a realistic search workload. If you can't show a first-query improvement, don't pay the refresh cost.
  • Preview plus an irreversible compatibility upgrade is a decision for dev first. Don't bump a production model's level for a preview feature without a rollback copy.
  • Put the XMLA step in the deployment pipeline up front if you go explicit, otherwise it gets forgotten and the index quietly never exists.
  • Watch the capacity memory metrics on the first full refresh after enabling it, not a fortnight later.

Revisit when string indexing reaches general availability or gains a UI.

Was this accurate?