Preskočiť na obsah
Návod

Columnstore a batch mode – Actual Execution Mode, segment elimination

Columnstore Index Scan a batch mode v pláne: Actual Execution Mode, Segments Read / Skipped, predicate a aggregate pushdown, delta store a batch mode on rowstore (2019+).

4 min čítania 4 kroky 1 obrázok SQL Server 2016+
> [!TIP]
> Recept z [kuchárky exekučných plánov](script.php?id=64&s=exekucne-plany-kucharka-zacni-tu). Ukážky bežia v testovacej databáze [PlanLab](script.php?id=65&s=planlab-testovacia-databaza-pre-recepty-exekucnych-planov) – nikdy ich nespúšťaj na produkcii.

## Ako to vyzerá v pláne

![Columnstore Index Scan v batch mode](uploads/2026/11/plan-o14.svg "Batch mode spracuje dávky riadkov; Segments Read / Skipped ukazuje, koľko sa dalo preskočiť")

V SSMS: **Columnstore Index Scan** a pri operátoroch vlastnosti **Estimated / Actual Execution Mode = Batch**. Batch mode môže mať aj Hash Match, Sort, Window Aggregate, Adaptive Join… Od SQL Server 2019 (compat 150) sa batch mode použije aj **bez columnstore** (*batch mode on rowstore*).

## Čo to znamená

**Columnstore index** ukladá dáta **po stĺpcoch** v komprimovaných segmentoch (~1 milión riadkov v *row group*). Dotaz číta len potrebné stĺpce a celé segmenty vie preskočiť podľa min/max hodnôt. **Batch mode** spracúva riadky v dávkach (rádovo stovky riadkov naraz) namiesto jedného riadku – pri analytických dotazoch nad miliónmi riadkov je to často rádovo rýchlejšie.

### Do hĺbky

- **Actual Segments Read / Skipped** – koľko segmentov sa čítalo a koľko preskočilo (*segment elimination*). Funguje dobre, keď sú dáta pri načítaní zoradené podľa filtrovaného stĺpca (napr. dátumu).
- **Predicate pushdown** – filter sa aplikuje už pri čítaní segmentu (vidíš ho v *Predicate* columnstore skenu, nie v samostatnom Filter).
- **Aggregate pushdown** – časť agregácie sa spočíta priamo pri skene; vlastnosť *Actual Number of Locally Aggregated Rows*.
- **Delta store** – nové riadky (malé dávky INSERT) čakajú v rowstore časti, kým sa neskomprimujú. Veľa riadkov v delta store = pomalší sken.
- **Batch mode on rowstore** (SQL Server 2019+, compat 150) – optimalizátor ho zvolí sám podľa heuristík (veľké tabuľky, agregácie, joiny). V tabuľke funkcií SQL Server 2022 je označený ako **Enterprise** (a Developer).
- Batch mode umožňuje aj [Adaptive Join](script.php?id=74&s=adaptive-join-hash-match-alebo-nested-loops-az-za-behu-2017), *Window Aggregate* ([window funkcie](script.php?id=80&s=window-funkcie-v-plane-segment-sequence-project-a-window-spool)) a memory grant feedback pre batch mode.
- V batch mode je *Actual Elapsed Time* operátora jeho vlastný čas (nie súčet s deťmi ako v row mode).

## Kedy je to v poriadku / kedy problém

| V poriadku | Problém |
|---|---|
| reporty a agregácie nad miliónmi riadkov | OLTP dotaz na jeden riadok cez columnstore (lepší je rowstore index) |
| veľa Segments Skipped pri filtri na dátum | Segments Skipped = 0 napriek filtru (dáta nie sú zoradené) |
| batch mode pri Hash Match a Sort | operátor v row mode medzi batch operátormi (prepínanie) |

## Ako si to vyskúšať

```sql
USE PlanLab;
SET STATISTICS IO, TIME ON;

-- 1) Bez columnstore (row mode, ak nie je compat 150+ s batch mode on rowstore)
SELECT ProductID, SUM(Qty * Price) AS trzba, COUNT(*) AS riadky
FROM dbo.OrderLines GROUP BY ProductID;

-- 2) Neklastrovaný columnstore index (SQL Server 2016+)
CREATE NONCLUSTERED COLUMNSTORE INDEX NCCI_Lab_Lines ON dbo.OrderLines (OrderID, ProductID, Qty, Price);

SELECT ProductID, SUM(Qty * Price) AS trzba, COUNT(*) AS riadky
FROM dbo.OrderLines GROUP BY ProductID;

-- 3) Filter na OrderID: koľko segmentov sa preskočilo?
SELECT SUM(Qty) FROM dbo.OrderLines WHERE OrderID > 290000;

DROP INDEX NCCI_Lab_Lines ON dbo.OrderLines;
```

Spusti s **Include Actual Execution Plan** (Ctrl+M). Pri Columnstore Index Scan a Hash Match pozri *Actual Execution Mode*, *Actual Segments Read / Skipped* a v *Messages* „segment reads“ / lob logical reads. Pri 900 000 riadkoch vzniká len jeden segment na stĺpec – pri väčších tabuľkách je segment elimination výraznejšia.

## Čo s tým

1. Analytické dotazy nad veľkými tabuľkami: neklastrovaný (OLTP + reporty) alebo klastrovaný columnstore (sklad dát).
2. Načítavaj dáta zoradené podľa najčastejšieho filtra (dátum) – zlepší segment elimination.
3. Pri SQL Server 2019+ over compat level 150+ a edíciu – batch mode on rowstore môže pomôcť aj bez columnstore.
4. Columnstore nepoužívaj na tabuľky s častými jednoriadkovými UPDATE / DELETE bez rozmyslu (delta store, fragmentácia).

## Súvisiace

- [Adaptive Join](script.php?id=74&s=adaptive-join-hash-match-alebo-nested-loops-az-za-behu-2017)
- [Window funkcie v pláne](script.php?id=80&s=window-funkcie-v-plane-segment-sequence-project-a-window-spool)
- [Hash Match](script.php?id=73&s=hash-match-hash-join-a-hash-aggregate-build-a-probe)
- [Stream Aggregate vs. Hash Aggregate](script.php?id=76&s=stream-aggregate-vs-hash-aggregate-group-by-v-plane)

## Zdroje

- [Microsoft Learn – Columnstore indexes: overview](https://learn.microsoft.com/sql/relational-databases/indexes/columnstore-indexes-overview)
- [Microsoft Learn – Query Processing Architecture Guide](https://learn.microsoft.com/sql/relational-databases/query-processing-architecture-guide)
- [Microsoft Learn – Intelligent query processing](https://learn.microsoft.com/sql/relational-databases/performance/intelligent-query-processing)
- [Microsoft Learn – Editions and supported features of SQL Server 2022](https://learn.microsoft.com/sql/sql-server/editions-and-components-of-sql-server-2022)
- [Hugo Kornelis – SQL Server Execution Plan Reference (SQLServerFast)](https://sqlserverfast.com/epr/)

_Texty sú vlastné, tvrdenia overené proti uvedeným zdrojom (11/2026). T-SQL je staticky skontrolovaný, nie spustený na živom serveri – vyskúšaj ho najprv v PlanLab._