MySQL
Benchmarks
How ARX compares with other ways of doing the same work on MySQL, measured with BenchmarkDotNet.
A living summary of the MySQL benchmarks: how ARX compares with raw MySqlConnector, Dapper and EF Core. Update it whenever a benchmark is rerun or an operation is added.
| Last updated | 2026-11-09: first full run of every operation (106 benchmarks, 32 minutes), then Execute rerun after ARX's own CALL by name |
| Operations measured | Create, CreateMultiple, Update, UpdateMultiple, Delete, DeleteMultiple, Retrieve, RetrieveMultiple (rows, a page with the total), Execute (a procedure with result rows and an OUT value, a scalar function) |
| Machine | Intel Core i7-8750H, Windows 11, .NET 10.0.14, MySQL 8.4.13 (mysql:8.4) in Docker Desktop, MySqlConnector 2.6.2, BenchmarkDotNet 0.15.8, job Standard (8 iterations, 3 warm-ups) |
| Compared with | Raw MySqlConnector (hand-written, typed parameters), Dapper 2.1.89, EF Core 9 through Pomelo 9.0.0 (the latest Pomelo; it has no EF Core 10 release yet), MySqlBulkCopy (LOAD DATA LOCAL INFILE, with local_infile turned on for the run) |
| Reports | The full run: results/2026-11-09-full-run/. Execute after the change: results/2026-11-09-execute-after-own-call.md. |
In one line: ARX is level with hand-written MySqlConnector for many-row writes and deletes, and far faster than EF Core (19โ37ร) and Dapper's row-by-row list execute (14โ190ร) for many-row writes; level with Dapper for single-row calls; level with raw and Dapper for reads up to 1,000 rows. Its gaps are a procedure call (1.1โ1.2ร) and large reads (1.36ร a typed reader at 10,000 rows, level with EF Core).
Read the ratios, not the absolute times, which depend on the machine. A single-row write here costs about 3 ms, nearly all of it MySQL's commit in Docker Desktop; differences under about 15% on a single run are inside the noise. One run of each benchmark so far: treat close calls as level.
Every operation at a glance (2026-11-09)
Mean times. "Raw" is the hand-written MySqlConnector form (a multi-row INSERT, UPDATE โฆ JOIN (VALUES ROW โฆ), one
IN list), the same shape of SQL ARX sends.
| Operation | ARX | Raw MySqlConnector | Dapper | EF Core | ARX vs raw |
|---|---|---|---|---|---|
| Create, one row | 3.85 ms | 3.29 ms | 3.86 ms | 7.01 ms | 1.17ร (level with Dapper) |
| CreateMultiple, 100 rows, ids back | 7.39 ms | 6.59 ms | โ | 138 ms | 1.12ร |
| CreateMultiple, 1,000 rows, ids back | 39.4 ms | 48.7 ms | โ | 1.41 s | 0.83ร |
| CreateMultiple, 10,000 rows, ids back | 426 ms | 397 ms | โ | 14.6 s | 1.09ร |
| CreateMultiple, 10,000 rows, no ids needed | 459 ms (still returns ids) | MySqlBulkCopy 152 ms |
one statement a row: 28.5 s | โ | 3.0ร MySqlBulkCopy |
| Update, one row | 1.60 ms | 1.49 ms | 1.33 ms | 2.35 ms | 1.08ร |
| UpdateMultiple, 100 rows | 4.64 ms | 4.05 ms | 66.7 ms | 27.4 ms | 1.15ร |
| UpdateMultiple, 1,000 rows | 45.2 ms | 44.1 ms | 681 ms | 329 ms | 1.04ร |
| UpdateMultiple, 10,000 rows | 481 ms | 436 ms | 6.93 s | 2.34 s | 1.15ร |
| Delete, one row | 5.19 ms | 5.36 ms | 5.27 ms | 13.3 ms | level |
| DeleteMultiple, 100 ids | 6.61 ms | 6.03 ms | 6.46 ms | 14.1 ms | 1.10ร |
| DeleteMultiple, 1,000 ids | 15.8 ms | 14.9 ms | 15.8 ms | 22.7 ms | 1.09ร |
| DeleteMultiple, 10,000 ids | 154 ms | 144 ms | 160 ms | 112 ms | 1.07ร (EF Core 0.78ร) |
| Retrieve, one row by id | 1.50 ms | 1.34 ms | 1.27 ms | 2.39 ms | 1.13ร |
| RetrieveMultiple, 100 rows | 1.97 ms | 1.93 ms | 2.01 ms | 2.40 ms | level |
| RetrieveMultiple, 1,000 rows | 5.29 ms | 4.79 ms | 4.92 ms | 6.03 ms | 1.11ร |
| RetrieveMultiple, 10,000 rows | 36.8 ms | typed 27.1 ms | 28.4 ms | 38.6 ms | 1.36ร typed; level with EF Core |
| A page of 50 with the total | 2.03โ4.83 ms | 1.78โ4.58 ms | โ | โ | 1.05โ1.14ร |
| Execute: a procedure, 1 row + an OUT value | 4.25 ms | 3.54 ms | 3.56 ms | no way to read OUT values | 1.20ร (1.31ร before the change) |
| Execute: a procedure, 1,000 rows | 5.44 ms | 4.45 ms | 4.73 ms | โ | 1.22ร (1.33ร before) |
| Execute: a scalar function | 1.45โ1.63 ms | 1.25โ1.34 ms | โ | โ | 1.09โ1.32ร |
The Dapper CreateMultiple and UpdateMultiple columns are ExecuteAsync(sql, list), one statement per row: what Dapper
does with a list. EF Core's numbers are Pomelo's batching (one statement per entity in a batch).
What the numbers say
- Many-row writes are level with hand-written multi-row SQL (0.83โ1.15ร): ARX sends multi-row statements of up to 1,000 rows and reads a whole statement's generated ids as one block, so returning ids in list order costs nothing extra. EF Core is 20โ37ร slower there, and Dapper's list execute 16โ190ร.
MySqlBulkCopyis 3.0ร faster for 10,000 rows when ids aren't needed. It needslocal_infileon the server andAllowLoadLocalInfileon the connection (both off by default, for safety), and returns no ids; ARX doesn't use it.- Single-row calls are level with Dapper and 1.1โ1.2ร raw: ARX adds its session statement (UTC and a strict SQL mode) to the call's round trip and builds an entity; the commit dominates.
- Deletes by id are level with raw and Dapper at every size: MySQL has no parameter limit (MySqlConnector writes the
values into the text) and searches a long
INlist well, so one list of up to 10,000 ids a statement is the best form. EF Core'sContainsis faster at 10,000 ids. - Reads are level with raw and Dapper up to 1,000 rows; at 10,000 rows ARX's dictionaries cost 1.36ร a typed reader (level with EF Core), as on PostgreSQL and SQL Server.
- A procedure call by name was 1.31โ1.40ร: MySqlConnector's own call needed a round trip of its own for ARX's
session statement. ARX now writes the
CALLitself, with the session statement,SHOW WARNINGSand the OUT values in one round trip: 1.12โ1.22ร. What is left is theSHOW WARNINGSthat collects messages (about 0.15 ms, measured;CollectMessages = falseskips it) and ARX's result building.
The reports
BenchmarkDotNet's own output for the runs the summary cites, as committed: every number above comes from one of these.
2026-11-09: full run Create.CreateBenchmarks
BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.9711/25H2/2025Update/HudsonValley2)
Intel Core i7-8750H CPU 2.20GHz (Max: 2.21GHz) (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET SDK 10.0.403
[Host] : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Standard : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Job=Standard IterationCount=8 LaunchCount=1
WarmupCount=3
| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
|---|---|---|---|---|---|---|---|---|
| 'Raw INSERT, LastInsertedId' | 3.291 ms | 0.1655 ms | 0.0735 ms | 1.00 | 0.03 | - | 9.43 KB | 1.00 |
| 'Dapper ExecuteScalar (INSERT; SELECT LAST_INSERT_ID())' | 3.862 ms | 0.3244 ms | 0.1697 ms | 1.17 | 0.05 | - | 8.78 KB | 0.93 |
| 'EF Core Add + SaveChanges' | 7.012 ms | 1.5166 ms | 0.6734 ms | 2.13 | 0.20 | 15.6250 | 108.29 KB | 11.48 |
| 'ARX CreateAsync' | 3.851 ms | 0.7913 ms | 0.3513 ms | 1.17 | 0.10 | - | 20.43 KB | 2.16 |
2026-11-09: full run Create.CreateMultipleBenchmarks
BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.9711/25H2/2025Update/HudsonValley2)
Intel Core i7-8750H CPU 2.20GHz (Max: 2.21GHz) (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET SDK 10.0.403
[Host] : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Standard : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Job=Standard IterationCount=8 LaunchCount=1
WarmupCount=3
| Method | Categories | Rows | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 'Raw MySqlBulkCopy (LOAD DATA LOCAL INFILE)' | CreateMultiple, ids not needed | 1 | 50.985 ms | 1.8772 ms | 0.6694 ms | 1.00 | 0.02 | - | - | - | 146.39 KB | 1.00 |
| 'Dapper ExecuteAsync(sql, list): one statement per row' | CreateMultiple, ids not needed | 1 | 3.634 ms | 0.5324 ms | 0.2784 ms | 0.07 | 0.01 | - | - | - | 8.34 KB | 0.06 |
| 'ARX CreateMultipleAsync (still returns ids)' | CreateMultiple, ids not needed | 1 | 3.732 ms | 0.4591 ms | 0.2401 ms | 0.07 | 0.00 | - | - | - | 19.52 KB | 0.13 |
| 'Raw MySqlBulkCopy (LOAD DATA LOCAL INFILE)' | CreateMultiple, ids not needed | 10 | 51.180 ms | 1.7518 ms | 0.9162 ms | 1.00 | 0.02 | - | - | - | 155.95 KB | 1.00 |
| 'Dapper ExecuteAsync(sql, list): one statement per row' | CreateMultiple, ids not needed | 10 | 26.653 ms | 1.7244 ms | 0.7656 ms | 0.52 | 0.02 | - | - | - | 44.87 KB | 0.29 |
| 'ARX CreateMultipleAsync (still returns ids)' | CreateMultiple, ids not needed | 10 | 4.985 ms | 0.8976 ms | 0.3985 ms | 0.10 | 0.01 | 7.8125 | - | - | 64.07 KB | 0.41 |
| 'Raw MySqlBulkCopy (LOAD DATA LOCAL INFILE)' | CreateMultiple, ids not needed | 100 | 50.371 ms | 0.1557 ms | 0.0555 ms | 1.00 | 0.00 | - | - | - | 220.05 KB | 1.00 |
| 'Dapper ExecuteAsync(sql, list): one statement per row' | CreateMultiple, ids not needed | 100 | 294.854 ms | 30.1582 ms | 15.7733 ms | 5.85 | 0.30 | - | - | - | 382.94 KB | 1.74 |
| 'ARX CreateMultipleAsync (still returns ids)' | CreateMultiple, ids not needed | 100 | 7.378 ms | 0.3136 ms | 0.1392 ms | 0.15 | 0.00 | 78.1250 | 15.6250 | - | 470 KB | 2.14 |
| 'Raw MySqlBulkCopy (LOAD DATA LOCAL INFILE)' | CreateMultiple, ids not needed | 1000 | 50.595 ms | 22.8597 ms | 11.9561 ms | 1.07 | 0.39 | 166.6667 | 83.3333 | - | 1023.16 KB | 1.00 |
| 'Dapper ExecuteAsync(sql, list): one statement per row' | CreateMultiple, ids not needed | 1000 | 2,884.046 ms | 459.9754 ms | 240.5760 ms | 60.78 | 18.24 | - | - | - | 3687.74 KB | 3.60 |
| 'ARX CreateMultipleAsync (still returns ids)' | CreateMultiple, ids not needed | 1000 | 60.429 ms | 26.4352 ms | 13.8261 ms | 1.27 | 0.47 | 750.0000 | 625.0000 | 250.0000 | 5073.59 KB | 4.96 |
| 'Raw MySqlBulkCopy (LOAD DATA LOCAL INFILE)' | CreateMultiple, ids not needed | 10000 | 152.083 ms | 26.1907 ms | 13.6983 ms | 1.01 | 0.12 | 1333.3333 | 333.3333 | - | 10451.82 KB | 1.00 |
| 'Dapper ExecuteAsync(sql, list): one statement per row' | CreateMultiple, ids not needed | 10000 | 28,549.272 ms | 2,599.9472 ms | 1,154.3927 ms | 189.00 | 16.90 | 7000.0000 | - | - | 36242.54 KB | 3.47 |
| 'ARX CreateMultipleAsync (still returns ids)' | CreateMultiple, ids not needed | 10000 | 459.024 ms | 87.5505 ms | 45.7906 ms | 3.04 | 0.38 | 6000.0000 | 3000.0000 | 1000.0000 | 48393.02 KB | 4.63 |
| 'Raw multi-row INSERT, ids from LastInsertedId' | CreateMultiple, returns ids | 1 | 3.210 ms | 0.2928 ms | 0.1531 ms | 1.00 | 0.06 | - | - | - | 10.59 KB | 1.00 |
| 'EF Core AddRange (typed)' | CreateMultiple, returns ids | 1 | 6.113 ms | 0.4609 ms | 0.2411 ms | 1.91 | 0.11 | 15.6250 | - | - | 106.2 KB | 10.03 |
| 'ARX CreateMultipleAsync' | CreateMultiple, returns ids | 1 | 3.696 ms | 0.6106 ms | 0.3193 ms | 1.15 | 0.11 | - | - | - | 19.52 KB | 1.84 |
| 'Raw multi-row INSERT, ids from LastInsertedId' | CreateMultiple, returns ids | 10 | 3.789 ms | 0.3420 ms | 0.1789 ms | 1.00 | 0.06 | 7.8125 | - | - | 51.23 KB | 1.00 |
| 'EF Core AddRange (typed)' | CreateMultiple, returns ids | 10 | 10.061 ms | 1.6276 ms | 0.8513 ms | 2.66 | 0.24 | 46.8750 | 15.6250 | - | 262.36 KB | 5.12 |
| 'ARX CreateMultipleAsync' | CreateMultiple, returns ids | 10 | 4.447 ms | 0.5483 ms | 0.2435 ms | 1.18 | 0.08 | 7.8125 | - | - | 64.09 KB | 1.25 |
| 'Raw multi-row INSERT, ids from LastInsertedId' | CreateMultiple, returns ids | 100 | 6.590 ms | 0.5850 ms | 0.3060 ms | 1.00 | 0.06 | 93.7500 | 31.2500 | 15.6250 | 496.27 KB | 1.00 |
| 'EF Core AddRange (typed)' | CreateMultiple, returns ids | 100 | 138.491 ms | 10.0528 ms | 4.4635 ms | 21.06 | 1.10 | 250.0000 | - | - | 1748.48 KB | 3.52 |
| 'ARX CreateMultipleAsync' | CreateMultiple, returns ids | 100 | 7.392 ms | 0.6540 ms | 0.3421 ms | 1.12 | 0.07 | 93.7500 | 7.8125 | - | 469.02 KB | 0.95 |
| 'Raw multi-row INSERT, ids from LastInsertedId' | CreateMultiple, returns ids | 1000 | 48.747 ms | 17.0559 ms | 8.9206 ms | 1.03 | 0.26 | 1000.0000 | 666.6667 | 333.3333 | 5490.07 KB | 1.00 |
| 'EF Core AddRange (typed)' | CreateMultiple, returns ids | 1000 | 1,414.156 ms | 26.2638 ms | 9.3659 ms | 29.93 | 5.49 | 2000.0000 | 1000.0000 | - | 16547.55 KB | 3.01 |
| 'ARX CreateMultipleAsync' | CreateMultiple, returns ids | 1000 | 39.423 ms | 8.5679 ms | 3.0554 ms | 0.83 | 0.16 | 875.0000 | 750.0000 | 375.0000 | 5113.82 KB | 0.93 |
| 'Raw multi-row INSERT, ids from LastInsertedId' | CreateMultiple, returns ids | 10000 | 396.868 ms | 105.9856 ms | 55.4325 ms | 1.02 | 0.20 | 8000.0000 | 3000.0000 | 1000.0000 | 53992.51 KB | 1.00 |
| 'EF Core AddRange (typed)' | CreateMultiple, returns ids | 10000 | 14,595.079 ms | 87.7110 ms | 45.8746 ms | 37.45 | 5.22 | 30000.0000 | 10000.0000 | 5000.0000 | 162084.05 KB | 3.00 |
| 'ARX CreateMultipleAsync' | CreateMultiple, returns ids | 10000 | 425.735 ms | 69.8353 ms | 36.5252 ms | 1.09 | 0.18 | 6000.0000 | 3000.0000 | 1000.0000 | 47880.88 KB | 0.89 |
2026-11-09: full run Delete.DeleteBenchmarks
BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.9711/25H2/2025Update/HudsonValley2)
Intel Core i7-8750H CPU 2.20GHz (Max: 2.21GHz) (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET SDK 10.0.403
[Host] : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
SingleOperation : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Job=SingleOperation InvocationCount=1 IterationCount=12
LaunchCount=1 RunStrategy=Monitoring UnrollFactor=1
WarmupCount=1
| Method | Rows | Mean | Error | StdDev | Median | Ratio | RatioSD | Allocated | Alloc Ratio |
|---|---|---|---|---|---|---|---|---|---|
| 'Raw DELETE โฆ IN (โฆ)' | 1 | 5.361 ms | 0.9505 ms | 0.7421 ms | 5.282 ms | 1.02 | 0.20 | 38.45 KB | 1.00 |
| 'Dapper ExecuteAsync(DELETE โฆ IN @ids)' | 1 | 5.274 ms | 1.0780 ms | 0.8416 ms | 5.048 ms | 1.00 | 0.21 | 43.02 KB | 1.12 |
| 'EF Core ExecuteDeleteAsync (Where ids.Contains)' | 1 | 13.325 ms | 30.2472 ms | 23.6150 ms | 6.070 ms | 2.53 | 4.37 | 133.59 KB | 3.47 |
| 'ARX DeleteAsync / DeleteMultipleAsync' | 1 | 5.193 ms | 0.7978 ms | 0.6229 ms | 4.960 ms | 0.99 | 0.18 | 43.94 KB | 1.14 |
| 'Raw DELETE โฆ IN (โฆ)' | 100 | 6.031 ms | 0.6103 ms | 0.4765 ms | 5.861 ms | 1.01 | 0.11 | 83.22 KB | 1.00 |
| 'Dapper ExecuteAsync(DELETE โฆ IN @ids)' | 100 | 6.464 ms | 0.7548 ms | 0.5893 ms | 6.353 ms | 1.08 | 0.12 | 79.94 KB | 0.96 |
| 'EF Core ExecuteDeleteAsync (Where ids.Contains)' | 100 | 14.100 ms | 28.1673 ms | 21.9912 ms | 7.756 ms | 2.35 | 3.54 | 147.59 KB | 1.77 |
| 'ARX DeleteAsync / DeleteMultipleAsync' | 100 | 6.614 ms | 1.0859 ms | 0.8478 ms | 6.442 ms | 1.10 | 0.16 | 86.67 KB | 1.04 |
| 'Raw DELETE โฆ IN (โฆ)' | 1000 | 14.889 ms | 4.3723 ms | 3.4136 ms | 13.931 ms | 1.03 | 0.27 | 552.74 KB | 1.00 |
| 'Dapper ExecuteAsync(DELETE โฆ IN @ids)' | 1000 | 15.818 ms | 5.4727 ms | 4.2727 ms | 14.359 ms | 1.10 | 0.33 | 451.89 KB | 0.82 |
| 'EF Core ExecuteDeleteAsync (Where ids.Contains)' | 1000 | 22.687 ms | 26.3663 ms | 20.5851 ms | 16.269 ms | 1.57 | 1.40 | 292.61 KB | 0.53 |
| 'ARX DeleteAsync / DeleteMultipleAsync' | 1000 | 15.791 ms | 4.3192 ms | 3.3722 ms | 14.824 ms | 1.09 | 0.27 | 506.59 KB | 0.92 |
| 'Raw DELETE โฆ IN (โฆ)' | 10000 | 144.260 ms | 15.2102 ms | 11.8751 ms | 143.650 ms | 1.01 | 0.11 | 5666.66 KB | 1.00 |
| 'Dapper ExecuteAsync(DELETE โฆ IN @ids)' | 10000 | 159.561 ms | 17.6149 ms | 13.7526 ms | 163.706 ms | 1.11 | 0.12 | 4292.58 KB | 0.76 |
| 'EF Core ExecuteDeleteAsync (Where ids.Contains)' | 10000 | 111.781 ms | 32.9749 ms | 25.7446 ms | 102.583 ms | 0.78 | 0.18 | 1712.08 KB | 0.30 |
| 'ARX DeleteAsync / DeleteMultipleAsync' | 10000 | 153.635 ms | 19.8671 ms | 15.5109 ms | 151.898 ms | 1.07 | 0.13 | 4888.67 KB | 0.86 |
2026-11-09: full run Execute.ExecuteBenchmarks
BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.9711/25H2/2025Update/HudsonValley2)
Intel Core i7-8750H CPU 2.20GHz (Max: 2.21GHz) (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET SDK 10.0.403
[Host] : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Standard : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Job=Standard IterationCount=8 LaunchCount=1
WarmupCount=3
| Method | Categories | Rows | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 'Raw CommandType.StoredProcedure, reader + OUT' | Procedure | 1 | 3.909 ms | 0.8584 ms | 0.3811 ms | 1.01 | 0.13 | - | - | 11.14 KB | 1.00 |
| 'Dapper QueryAsync + DynamicParameters output' | Procedure | 1 | 3.573 ms | 0.1859 ms | 0.0825 ms | 0.92 | 0.08 | - | - | 13.04 KB | 1.17 |
| 'ARX ExecuteAsync (procedure, by name)' | Procedure | 1 | 5.071 ms | 0.2494 ms | 0.1107 ms | 1.31 | 0.12 | - | - | 22.55 KB | 2.02 |
| 'ARX ExecuteAsync (procedure, by position)' | Procedure | 1 | NA | NA | NA | ? | ? | NA | NA | NA | ? |
| 'Raw CommandType.StoredProcedure, reader + OUT' | Procedure | 100 | 3.803 ms | 0.3906 ms | 0.2043 ms | 1.00 | 0.07 | - | - | 10.86 KB | 1.00 |
| 'Dapper QueryAsync + DynamicParameters output' | Procedure | 100 | 3.787 ms | 0.2634 ms | 0.1170 ms | 1.00 | 0.06 | - | - | 31.58 KB | 2.91 |
| 'ARX ExecuteAsync (procedure, by name)' | Procedure | 100 | 5.305 ms | 0.3729 ms | 0.1950 ms | 1.40 | 0.09 | 7.8125 | - | 53.97 KB | 4.97 |
| 'ARX ExecuteAsync (procedure, by position)' | Procedure | 100 | NA | NA | NA | ? | ? | NA | NA | NA | ? |
| 'Raw CommandType.StoredProcedure, reader + OUT' | Procedure | 1000 | 4.756 ms | 0.6859 ms | 0.3045 ms | 1.00 | 0.08 | - | - | 11.14 KB | 1.00 |
| 'Dapper QueryAsync + DynamicParameters output' | Procedure | 1000 | 5.268 ms | 0.8490 ms | 0.4440 ms | 1.11 | 0.11 | 39.0625 | 7.8125 | 193.35 KB | 17.36 |
| 'ARX ExecuteAsync (procedure, by name)' | Procedure | 1000 | 6.302 ms | 0.5875 ms | 0.2608 ms | 1.33 | 0.09 | 62.5000 | 15.6250 | 335.81 KB | 30.16 |
| 'ARX ExecuteAsync (procedure, by position)' | Procedure | 1000 | NA | NA | NA | ? | ? | NA | NA | NA | ? |
| 'Raw SELECT fn(@a, @b)' | Scalar function | 1 | 1.343 ms | 0.2945 ms | 0.1308 ms | 1.01 | 0.13 | - | - | 5.64 KB | 1.00 |
| 'ARX ExecuteAsync (scalar function)' | Scalar function | 1 | 1.454 ms | 0.0650 ms | 0.0289 ms | 1.09 | 0.09 | 1.9531 | - | 13.94 KB | 2.47 |
| 'Raw SELECT fn(@a, @b)' | Scalar function | 100 | 1.245 ms | 0.0690 ms | 0.0361 ms | 1.00 | 0.04 | - | - | 5.69 KB | 1.00 |
| 'ARX ExecuteAsync (scalar function)' | Scalar function | 100 | 1.634 ms | 0.4498 ms | 0.2352 ms | 1.31 | 0.18 | 1.9531 | - | 13.87 KB | 2.44 |
| 'Raw SELECT fn(@a, @b)' | Scalar function | 1000 | 1.294 ms | 0.1884 ms | 0.0985 ms | 1.00 | 0.10 | - | - | 5.86 KB | 1.00 |
| 'ARX ExecuteAsync (scalar function)' | Scalar function | 1000 | 1.507 ms | 0.1575 ms | 0.0824 ms | 1.17 | 0.10 | 1.9531 | - | 13.86 KB | 2.37 |
Benchmarks with issues: ExecuteBenchmarks.'ARX ExecuteAsync (procedure, by position)': Standard(IterationCount=8, LaunchCount=1, WarmupCount=3) [Rows=1] ExecuteBenchmarks.'ARX ExecuteAsync (procedure, by position)': Standard(IterationCount=8, LaunchCount=1, WarmupCount=3) [Rows=100] ExecuteBenchmarks.'ARX ExecuteAsync (procedure, by position)': Standard(IterationCount=8, LaunchCount=1, WarmupCount=3) [Rows=1000]
2026-11-09: full run Retrieve.RetrieveBenchmarks
BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.9711/25H2/2025Update/HudsonValley2)
Intel Core i7-8750H CPU 2.20GHz (Max: 2.21GHz) (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET SDK 10.0.403
[Host] : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Standard : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Job=Standard IterationCount=8 LaunchCount=1
WarmupCount=3
| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
|---|---|---|---|---|---|---|---|---|
| 'Raw MySqlDataReader by id' | 1.338 ms | 0.2280 ms | 0.1193 ms | 1.01 | 0.12 | - | 8.24 KB | 1.00 |
| 'Dapper QuerySingle<T>' | 1.273 ms | 0.0775 ms | 0.0344 ms | 0.96 | 0.08 | 1.9531 | 11.07 KB | 1.34 |
| 'EF Core AsNoTracking FirstAsync' | 2.386 ms | 0.3475 ms | 0.1817 ms | 1.80 | 0.19 | 19.5313 | 91.04 KB | 11.06 |
| 'ARX RetrieveAsync by id' | 1.500 ms | 0.1585 ms | 0.0829 ms | 1.13 | 0.11 | 1.9531 | 14.82 KB | 1.80 |
2026-11-09: full run Retrieve.RetrieveMultipleBenchmarks
BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.9711/25H2/2025Update/HudsonValley2)
Intel Core i7-8750H CPU 2.20GHz (Max: 2.21GHz) (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET SDK 10.0.403
[Host] : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Standard : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Job=Standard IterationCount=8 LaunchCount=1
WarmupCount=3
| Method | Categories | Rows | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 'Raw MySqlDataReader, id range' | **** | 100 | 2.095 ms | 0.3767 ms | 0.1970 ms | 1.01 | 0.13 | 7.8125 | - | - | 48.02 KB | 1.00 |
| 'Dapper Query<T>' | 100 | 2.323 ms | 0.8743 ms | 0.4573 ms | 1.12 | 0.23 | 7.8125 | - | - | 53.36 KB | 1.11 | |
| 'EF Core AsNoTracking ToListAsync' | 100 | 3.521 ms | 0.8860 ms | 0.4634 ms | 1.69 | 0.26 | 31.2500 | - | - | 156.78 KB | 3.26 | |
| 'ARX RetrieveMultipleAsync' | 100 | 2.023 ms | 0.2362 ms | 0.1049 ms | 0.97 | 0.10 | 15.6250 | 3.9063 | - | 86.46 KB | 1.80 | |
| 'Raw MySqlDataReader, id range' | **** | 1000 | 5.461 ms | 0.5125 ms | 0.2680 ms | 1.00 | 0.07 | 78.1250 | 15.6250 | - | 408.35 KB | 1.00 |
| 'Dapper Query<T>' | 1000 | 4.694 ms | 0.2051 ms | 0.0911 ms | 0.86 | 0.04 | 85.9375 | 23.4375 | - | 433.7 KB | 1.06 | |
| 'EF Core AsNoTracking ToListAsync' | 1000 | 5.973 ms | 2.1551 ms | 0.9569 ms | 1.10 | 0.17 | 140.6250 | 15.6250 | - | 712.82 KB | 1.75 | |
| 'ARX RetrieveMultipleAsync' | 1000 | 4.931 ms | 0.6206 ms | 0.2755 ms | 0.90 | 0.06 | 125.0000 | 78.1250 | - | 690.9 KB | 1.69 | |
| 'Raw MySqlDataReader, id range' | **** | 10000 | 30.040 ms | 5.3551 ms | 2.3777 ms | 1.01 | 0.11 | 625.0000 | 281.2500 | 125.0000 | 4109.09 KB | 1.00 |
| 'Dapper Query<T>' | 10000 | 29.015 ms | 2.7144 ms | 1.4197 ms | 0.97 | 0.08 | 625.0000 | 250.0000 | 125.0000 | 4348.85 KB | 1.06 | |
| 'EF Core AsNoTracking ToListAsync' | 10000 | 37.481 ms | 2.8551 ms | 1.0182 ms | 1.25 | 0.10 | 1000.0000 | 375.0000 | 125.0000 | 6365.34 KB | 1.55 | |
| 'ARX RetrieveMultipleAsync' | 10000 | 40.360 ms | 2.7827 ms | 0.9924 ms | 1.35 | 0.11 | 1142.8571 | 571.4286 | 142.8571 | 6802.67 KB | 1.66 | |
| 'Raw page of 50 + COUNT(*) in one command' | Page | 100 | 1.751 ms | 0.2534 ms | 0.1325 ms | ? | ? | - | - | - | 8.65 KB | ? |
| 'ARX page of 50 with the total' | Page | 100 | 1.949 ms | 0.1007 ms | 0.0527 ms | ? | ? | 11.7188 | - | - | 55.28 KB | ? |
| 'Raw page of 50 + COUNT(*) in one command' | Page | 1000 | 1.991 ms | 0.1367 ms | 0.0715 ms | ? | ? | - | - | - | 9.29 KB | ? |
| 'ARX page of 50 with the total' | Page | 1000 | 2.248 ms | 0.2028 ms | 0.1061 ms | ? | ? | 11.7188 | - | - | 56.87 KB | ? |
| 'Raw page of 50 + COUNT(*) in one command' | Page | 10000 | 4.581 ms | 0.2554 ms | 0.1336 ms | ? | ? | - | - | - | 9.52 KB | ? |
| 'ARX page of 50 with the total' | Page | 10000 | 4.707 ms | 0.1664 ms | 0.0739 ms | ? | ? | 7.8125 | - | - | 57.11 KB | ? |
2026-11-09: full run Update.UpdateBenchmarks
BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.9711/25H2/2025Update/HudsonValley2)
Intel Core i7-8750H CPU 2.20GHz (Max: 2.21GHz) (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET SDK 10.0.403
[Host] : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Standard : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Job=Standard IterationCount=8 LaunchCount=1
WarmupCount=3
| Method | Rows | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 'Raw UPDATE โฆ JOIN (VALUES ROW โฆ) (one row: plain UPDATE)' | 1 | 1.491 ms | 0.3857 ms | 0.1712 ms | 1.01 | 0.16 | 1.9531 | - | - | 8.91 KB | 1.00 |
| 'Dapper ExecuteAsync(sql, list): one statement per row' | 1 | 1.330 ms | 0.0671 ms | 0.0351 ms | 0.90 | 0.10 | - | - | - | 8.42 KB | 0.94 |
| 'EF Core Attach, all modified, SaveChanges' | 1 | 2.352 ms | 0.5930 ms | 0.3102 ms | 1.60 | 0.27 | 19.5313 | - | - | 101.3 KB | 11.37 |
| 'ARX UpdateAsync / UpdateMultipleAsync' | 1 | 1.595 ms | 0.2535 ms | 0.1126 ms | 1.08 | 0.14 | 3.9063 | - | - | 22.68 KB | 2.54 |
| 'Raw UPDATE โฆ JOIN (VALUES ROW โฆ) (one row: plain UPDATE)' | 100 | 4.049 ms | 0.2485 ms | 0.1300 ms | 1.00 | 0.04 | 109.3750 | 15.6250 | - | 537.4 KB | 1.00 |
| 'Dapper ExecuteAsync(sql, list): one statement per row' | 100 | 66.730 ms | 2.5779 ms | 1.1446 ms | 16.49 | 0.55 | - | - | - | 399.31 KB | 0.74 |
| 'EF Core Attach, all modified, SaveChanges' | 100 | 27.448 ms | 1.0041 ms | 0.5252 ms | 6.78 | 0.23 | 285.7143 | 142.8571 | - | 1672.17 KB | 3.11 |
| 'ARX UpdateAsync / UpdateMultipleAsync' | 100 | 4.641 ms | 0.2215 ms | 0.0984 ms | 1.15 | 0.04 | 109.3750 | 39.0625 | - | 577 KB | 1.07 |
| 'Raw UPDATE โฆ JOIN (VALUES ROW โฆ) (one row: plain UPDATE)' | 1000 | 44.148 ms | 12.0398 ms | 6.2970 ms | 1.02 | 0.19 | 923.0769 | 615.3846 | 307.6923 | 5793.8 KB | 1.00 |
| 'Dapper ExecuteAsync(sql, list): one statement per row' | 1000 | 680.642 ms | 61.8628 ms | 32.3555 ms | 15.69 | 2.21 | - | - | - | 3889.15 KB | 0.67 |
| 'EF Core Attach, all modified, SaveChanges' | 1000 | 329.137 ms | 86.7544 ms | 45.3742 ms | 7.59 | 1.42 | 2000.0000 | 1000.0000 | - | 16090.41 KB | 2.78 |
| 'ARX UpdateAsync / UpdateMultipleAsync' | 1000 | 45.209 ms | 28.4921 ms | 14.9019 ms | 1.04 | 0.36 | 1000.0000 | 571.4286 | 285.7143 | 5749.89 KB | 0.99 |
| 'Raw UPDATE โฆ JOIN (VALUES ROW โฆ) (one row: plain UPDATE)' | 10000 | 436.231 ms | 175.0523 ms | 91.5558 ms | 1.04 | 0.29 | 8000.0000 | 3000.0000 | 1000.0000 | 57101.79 KB | 1.00 |
| 'Dapper ExecuteAsync(sql, list): one statement per row' | 10000 | 6,931.689 ms | 323.7951 ms | 143.7670 ms | 16.52 | 3.28 | 8000.0000 | - | - | 38620.79 KB | 0.68 |
| 'EF Core Attach, all modified, SaveChanges' | 10000 | 2,342.840 ms | 190.5110 ms | 99.6409 ms | 5.58 | 1.13 | 30000.0000 | 10000.0000 | 5000.0000 | 159489.34 KB | 2.79 |
| 'ARX UpdateAsync / UpdateMultipleAsync' | 10000 | 480.610 ms | 160.1125 ms | 83.7419 ms | 1.15 | 0.30 | 7000.0000 | 4000.0000 | 1000.0000 | 58430.77 KB | 1.02 |
2026-11-09: execute after own call
BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.9711/25H2/2025Update/HudsonValley2)
Intel Core i7-8750H CPU 2.20GHz (Max: 2.21GHz) (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET SDK 10.0.403
[Host] : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Standard : .NET 10.0.14 (10.0.14, 10.0.1426.52326), X64 RyuJIT x86-64-v3
Job=Standard IterationCount=8 LaunchCount=1
WarmupCount=3
| Method | Categories | Rows | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 'Raw CommandType.StoredProcedure, reader + OUT' | Procedure | 1 | 3.544 ms | 0.1197 ms | 0.0531 ms | 1.00 | 0.02 | - | - | 10.81 KB | 1.00 |
| 'Dapper QueryAsync + DynamicParameters output' | Procedure | 1 | 3.557 ms | 0.2374 ms | 0.1054 ms | 1.00 | 0.03 | - | - | 13.33 KB | 1.23 |
| 'ARX ExecuteAsync (procedure, by name)' | Procedure | 1 | 4.249 ms | 0.3917 ms | 0.2049 ms | 1.20 | 0.06 | - | - | 20.3 KB | 1.88 |
| 'Raw CommandType.StoredProcedure, reader + OUT' | Procedure | 100 | 3.664 ms | 0.2008 ms | 0.1050 ms | 1.00 | 0.04 | - | - | 11.17 KB | 1.00 |
| 'Dapper QueryAsync + DynamicParameters output' | Procedure | 100 | 3.786 ms | 0.4422 ms | 0.1963 ms | 1.03 | 0.06 | - | - | 31.59 KB | 2.83 |
| 'ARX ExecuteAsync (procedure, by name)' | Procedure | 100 | 4.095 ms | 0.3083 ms | 0.1612 ms | 1.12 | 0.05 | 7.8125 | - | 51.53 KB | 4.61 |
| 'Raw CommandType.StoredProcedure, reader + OUT' | Procedure | 1000 | 4.447 ms | 0.2231 ms | 0.1167 ms | 1.00 | 0.03 | - | - | 10.86 KB | 1.00 |
| 'Dapper QueryAsync + DynamicParameters output' | Procedure | 1000 | 4.734 ms | 0.0878 ms | 0.0390 ms | 1.07 | 0.03 | 39.0625 | 7.8125 | 193.1 KB | 17.78 |
| 'ARX ExecuteAsync (procedure, by name)' | Procedure | 1000 | 5.437 ms | 0.7389 ms | 0.3864 ms | 1.22 | 0.09 | 62.5000 | 15.6250 | 333.35 KB | 30.69 |
| 'Raw SELECT fn(@a, @b)' | Scalar function | 1 | 1.316 ms | 0.1261 ms | 0.0660 ms | 1.00 | 0.07 | - | - | 5.75 KB | 1.00 |
| 'ARX ExecuteAsync (scalar function)' | Scalar function | 1 | 1.496 ms | 0.0867 ms | 0.0385 ms | 1.14 | 0.06 | 1.9531 | - | 13.87 KB | 2.41 |
| 'Raw SELECT fn(@a, @b)' | Scalar function | 100 | 1.249 ms | 0.0650 ms | 0.0340 ms | 1.00 | 0.04 | - | - | 5.69 KB | 1.00 |
| 'ARX ExecuteAsync (scalar function)' | Scalar function | 100 | 1.644 ms | 0.5582 ms | 0.2919 ms | 1.32 | 0.22 | 1.9531 | - | 13.86 KB | 2.44 |
| 'Raw SELECT fn(@a, @b)' | Scalar function | 1000 | 1.298 ms | 0.0967 ms | 0.0429 ms | 1.00 | 0.04 | - | - | 5.78 KB | 1.00 |
| 'ARX ExecuteAsync (scalar function)' | Scalar function | 1000 | 1.537 ms | 0.1839 ms | 0.0962 ms | 1.19 | 0.08 | - | - | 13.98 KB | 2.42 |
Run them yourself
The benchmark code is published, so you can check these numbers on your own machine and database: arx-benchmark-mysql.zip. It builds against the ARX packages on nuget.org; HOW-TO-RUN.md inside says how to point it at a database and run it. Compare the ratios, not the absolute times.