Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
191e2a5
PERF: Cache full column counts for fetchone
jahnvi480 Oct 1, 2026
814de78
FIX: Isolate mixed fetch cache test connections
jahnvi480 Oct 1, 2026
6fdfe89
Merge branch 'main' into jahnvi/candidate-a-fetchone-column-count
jahnvi480 Oct 1, 2026
492dd7a
Merge branch 'main' into jahnvi/candidate-a-fetchone-column-count
jahnvi480 Oct 5, 2026
7576322
Merge branch 'main' into jahnvi/candidate-a-fetchone-column-count
jahnvi480 Oct 5, 2026
4c43081
PERF: Consolidate single-row fetch optimizations
jahnvi480 Oct 5, 2026
ac6e988
FIX: Match single-row tests to native profiler and bind errors
jahnvi480 Oct 5, 2026
cc75f50
PERF: Reduce single-row count and value construction overhead
jahnvi480 Oct 6, 2026
80487e1
PERF: Add guarded shared fetch and Row construction
jahnvi480 Oct 6, 2026
08d5701
FIX: Correct parametrized fetch regression test signature
jahnvi480 Oct 6, 2026
81494a2
Merge branch 'main' into jahnvi/candidate-a-fetchone-column-count
jahnvi480 Oct 6, 2026
f539caf
PERF: Wire latency-first single-row PR performance reports
jahnvi480 Oct 6, 2026
3e7fcff
PERF: simplify fetchone routing and attest per-method report routes
jahnvi480 Oct 6, 2026
8a4472b
FIX: Align fetch recovery spies and annotate source fingerprints
jahnvi480 Oct 7, 2026
06eba44
FIX: Restore original PR performance report presentation
jahnvi480 Oct 7, 2026
4dbfb55
PERF: Use inline scratch storage for small NVARCHAR fetches
jahnvi480 Oct 7, 2026
2695900
CHORE: Keep fetch tests focused on driver coverage
jahnvi480 Oct 8, 2026
1468a23
PERF: Remove fetchmany single-row construction detour
jahnvi480 Oct 8, 2026
c928b63
PERF: Reduce fetch options, LOB copies, and converter dispatch
jahnvi480 Oct 8, 2026
84db936
FIX: Correct LOB fixtures and benchmark review findings
jahnvi480 Oct 8, 2026
d533112
DOC: Explain bounded fetchmany batching
jahnvi480 Oct 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,45 @@ for row in rows:
connection.close()

```

### Processing large results in batches

Use `cursor.fetchmany(1000)` to retrieve up to 1,000 rows per call and process each
batch before fetching the next. The final batch can be smaller; an empty list
means there are no more rows. Compared with calling `fetchone()` for every row,
batching can reduce per-call overhead without retaining the entire result in
application memory.

Set `DB_CONNECTION_STRING` for your database before running this example, which
uses the same AdventureWorksLT sample schema as above:

```python
import os

import mssql_python

with mssql_python.connect(os.environ["DB_CONNECTION_STRING"]) as connection:
with connection.cursor() as cursor:
cursor.execute("SELECT CustomerID, FirstName, LastName FROM SalesLT.Customer")
while rows := cursor.fetchmany(1000):
for row in rows:
print(row)
```

Replace `print(row)` with processing that does not retain earlier rows or batches.
Choose a batch size for your workload, row widths, and available memory; 1,000 is
an example, not a universally optimal size. Larger batches retain more rows at a
time, and large individual values can still require substantial memory.

`fetchall()` returns all remaining rows in a list. Similarly, accumulating every
batch in a list retains the full result and loses the memory benefit of consuming
and discarding batches.

This uses the existing `fetchmany(size)` API and does not change `cursor.arraysize`
or any driver defaults. Without an explicit size, `fetchmany()` uses
`cursor.arraysize`, whose default is 1. Batching requires changing the application's
fetch loop; it does not add read-ahead to, or automatically accelerate, existing
`fetchone()` loops.

## Still have questions?

Expand Down
2 changes: 1 addition & 1 deletion eng/pipelines/pr-validation-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,7 @@ jobs:
ACCEPT_EULA=Y apt-get install -y --no-install-recommends git unixodbc unixodbc-dev libodbc2 libodbcinst2 odbcinst msodbcsql18
git config --global --add safe.directory /workspace
odbcinst -q -d -n "ODBC Driver 18 for SQL Server"
python -m eng.profiler_benchmarks.controller --reuse-candidate --leg "$(profilerLeg)" --output profiler-results
python -m eng.profiler_benchmarks.controller --reuse-candidate --ci-report --leg "$(profilerLeg)" --output profiler-results
'
else
echo "Skipping performance benchmarks on $(distroName) (only runs on Ubuntu with local SQL Server)"
Expand Down
Loading
Loading