# TiDB BATCH ON shard-column and actual batch-size semantics

Use this topic only for TiDB non-transactional DML written with
`BATCH ON <column> LIMIT <N>`, or when the customer is explicitly asking how
that batching chooses ranges and actual transaction sizes.

- `BATCH ON` splits one DML statement into ordered ranges of the shard column.
  `LIMIT N` guides how the shard-column values are grouped; it is not a hard
  upper bound on the rows affected by each generated DML statement.
- When the boundary shard-column value is duplicated, a batch contains all
  rows with that duplicated boundary value. A low-cardinality timestamp column
  can therefore produce an actual batch far larger than `LIMIT`, and lowering
  only `LIMIT` below that duplicate group might not reduce the transaction.
- Prefer an indexed shard column with few duplicate values that also lets the
  original `WHERE` condition be evaluated efficiently. A clustered primary key
  is often a good candidate, but do not claim that `id` is universally correct
  without checking the table definition, index, predicate, and data
  distribution supplied in the ticket.
- Before execution, use `DRY RUN QUERY` to inspect the range-discovery query and
  `DRY RUN` to inspect the generated statements. Verify the actual affected
  rows per batch instead of treating the configured `LIMIT` as proof of the
  transaction size.
- There is no universal safe `LIMIT`. When an incident already shows an
  oversized write transaction, first fix an ineffective shard column, then use
  a smaller reversible starting value and adjust it from actual affected rows,
  end-to-end batch latency, write keys or Regions, prewrite/commit latency, and
  lock or latch impact. Do not quote a generic documentation example as the
  production threshold.
- This product behavior can explain why a configured batch limit did not take
  effect. It does not by itself prove that the resulting transaction caused a
  specific alert. Preserve the separate incident-evidence boundary and the
  strongest concurrent-write or storage alternative.

Official references:

- https://docs.pingcap.com/tidb/stable/non-transactional-dml/
- https://docs.pingcap.com/tidb/stable/sql-statement-batch/
