Skip to content

Commit 3d76f30

Browse files
fix: add indexes for read benchmark queries
1 parent 14efdb7 commit 3d76f30

19 files changed

Lines changed: 114 additions & 142 deletions

benchmark/BenchmarkRunner/Benchmarks/BaseReadBenchmark.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33

44
public abstract class BaseReadBenchmark
55
{
6-
protected const int CustomerCount = 500;
7-
86
[Params(100, 500)]
97
public int Limit { get; set; }
108

@@ -13,6 +11,12 @@ public abstract class BaseReadBenchmark
1311
public abstract Task Sqlc_GetCustomerOrders();
1412
public abstract Task EFCore_NoTracking_GetCustomerOrders();
1513
public abstract Task EFCore_WithTracking_GetCustomerOrders();
14+
public static DatabaseSeedConfig GetSeedConfig() => new(
15+
CustomerCount: 500,
16+
ProductsPerCategory: 150,
17+
OrdersPerCustomer: 500,
18+
ItemsPerOrder: 20
19+
);
1620
private static int CalculateMaxConcurrency(int totalTasks, int maxConcurrency)
1721
{
1822
return new int[] {

benchmark/BenchmarkRunner/Benchmarks/BaseWriteBenchmark.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22

33
public abstract class BaseWriteBenchmark
44
{
5-
[Params(2000000)]
6-
public int TotalRecords { get; set; }
5+
public static DatabaseSeedConfig GetSeedConfig() => new(
6+
CustomerCount: 500,
7+
ProductsPerCategory: 150,
8+
OrdersPerCustomer: 500,
9+
ItemsPerOrder: 0
10+
);
711

812
public abstract Task Sqlc_AddOrderItems(int batchSize);
913
public abstract Task EFCore_AddOrderItems(int batchSize);

benchmark/BenchmarkRunner/Benchmarks/MysqlReadBenchmark.cs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class MysqlReadBenchmark : BaseReadBenchmark
1717
private static readonly string _connectionString = Config.GetMysqlConnectionString();
1818
private readonly QuerySql _sqlcImpl = new(_connectionString);
1919

20-
[Params(3000)]
20+
[Params(3_000)]
2121
public int QueriesToRun { get; set; }
2222

2323
[Params(200, 500)]
@@ -30,7 +30,7 @@ public override async Task Sqlc_GetCustomerOrders()
3030
await ExecuteConcurrentlyAsync(QueriesToRun, ConcurrentQueries, _ =>
3131
{
3232
return _sqlcImpl.GetCustomerOrdersAsync(new QuerySql.GetCustomerOrdersArgs(
33-
CustomerId: Random.Shared.Next(1, CustomerCount),
33+
CustomerId: Random.Shared.Next(1, GetSeedConfig().CustomerCount),
3434
Offset: 0,
3535
Limit: Limit
3636
));
@@ -46,7 +46,7 @@ await ExecuteConcurrentlyAsync(QueriesToRun, ConcurrentQueries, async _ =>
4646
await using var dbContext = new SalesDbContext(_connectionString);
4747
var queries = new Queries(dbContext, useTracking: false);
4848
return await queries.GetCustomerOrders(new Queries.GetCustomerOrdersArgs(
49-
CustomerId: Random.Shared.Next(1, CustomerCount),
49+
CustomerId: Random.Shared.Next(1, GetSeedConfig().CustomerCount),
5050
Offset: 0,
5151
Limit: Limit
5252
));
@@ -62,7 +62,7 @@ await ExecuteConcurrentlyAsync(QueriesToRun, ConcurrentQueries, async _ =>
6262
await using var dbContext = new SalesDbContext(_connectionString);
6363
var queries = new Queries(dbContext, useTracking: true);
6464
return await queries.GetCustomerOrders(new Queries.GetCustomerOrdersArgs(
65-
CustomerId: Random.Shared.Next(1, CustomerCount),
65+
CustomerId: Random.Shared.Next(1, GetSeedConfig().CustomerCount),
6666
Offset: 0,
6767
Limit: Limit
6868
));
@@ -73,13 +73,8 @@ public static Func<Task> GetSeedMethod()
7373
{
7474
return async () =>
7575
{
76-
var seeder = new MysqlDatabaseSeeder(_connectionString);
77-
await seeder.SeedAsync(
78-
customerCount: 500, // selectivity: 1/500 of the table returned
79-
productsPerCategory: 150,
80-
ordersPerCustomer: 1000,
81-
itemsPerOrder: 20 // 20 * 1000 = 20,000 possible rows returned
82-
);
76+
var seeder = new MysqlSeeder(_connectionString);
77+
await seeder.SeedAsync(GetSeedConfig());
8378
};
8479
}
8580
}

benchmark/BenchmarkRunner/Benchmarks/MysqlWriteBenchmark.cs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using BenchmarkDotNet.Configs;
44
using BenchmarkDotNet.Jobs;
55
using BenchmarkRunner.Utils;
6+
using MySqlConnector;
67
using MysqlEFCoreImpl;
78
using MysqlSqlcImpl;
89

@@ -20,11 +21,13 @@ public class MysqlWriteBenchmark : BaseWriteBenchmark
2021
private readonly Queries _efCoreImpl = new(new SalesDbContext(_connectionString), useTracking: false);
2122
private List<QuerySql.AddOrderItemsArgs> _testOrderItems = null!;
2223

24+
[Params(1_250_000)]
25+
public int TotalRecords { get; set; }
26+
2327
[BenchmarkCategory("Write")]
2428
[Benchmark(Baseline = true, Description = "SQLC - AddOrderItems")]
25-
[Arguments(1000)]
26-
[Arguments(5000)]
27-
[Arguments(20000)]
29+
[Arguments(1_000)]
30+
[Arguments(2_000)]
2831
public override async Task Sqlc_AddOrderItems(int batchSize)
2932
{
3033
await Helpers.InsertInBatchesAsync(_testOrderItems, batchSize, _sqlcImpl.AddOrderItemsAsync);
@@ -45,13 +48,8 @@ public static Func<Task> GetSeedMethod()
4548
{
4649
return async () =>
4750
{
48-
var seeder = new MysqlDatabaseSeeder(_connectionString);
49-
await seeder.SeedAsync(
50-
customerCount: 10,
51-
productsPerCategory: 15,
52-
ordersPerCustomer: 300,
53-
itemsPerOrder: 0
54-
);
51+
var seeder = new MysqlSeeder(_connectionString);
52+
await seeder.SeedAsync(GetSeedConfig());
5553
};
5654
}
5755

@@ -72,7 +70,15 @@ public async Task GlobalSetup()
7270
[IterationSetup]
7371
public static void IterationSetup()
7472
{
75-
MysqlDatabaseHelper.CleanupWriteTableAsync(_connectionString).GetAwaiter().GetResult();
73+
CleanupWriteTableAsync(_connectionString).GetAwaiter().GetResult();
7674
Helpers.InvokeGarbageCollection();
7775
}
76+
77+
private static async Task CleanupWriteTableAsync(string connectionString)
78+
{
79+
using var connection = new MySqlConnection(connectionString);
80+
await connection.OpenAsync();
81+
using var cmd = new MySqlCommand("TRUNCATE TABLE sales.order_items", connection);
82+
await cmd.ExecuteNonQueryAsync();
83+
}
7884
}

benchmark/BenchmarkRunner/Benchmarks/PostgresqlReadBenchmark.cs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class PostgresqlReadBenchmark : BaseReadBenchmark
1717
private static readonly string _connectionString = Config.GetPostgresConnectionString();
1818
private readonly QuerySql _sqlcImpl = new(_connectionString);
1919

20-
[Params(1000)]
20+
[Params(1_000)]
2121
public int QueriesToRun { get; set; }
2222

2323
[Params(20, 50)]
@@ -30,7 +30,7 @@ public override async Task Sqlc_GetCustomerOrders()
3030
await ExecuteConcurrentlyAsync(QueriesToRun, ConcurrentQueries, _ =>
3131
{
3232
return _sqlcImpl.GetCustomerOrdersAsync(new QuerySql.GetCustomerOrdersArgs(
33-
CustomerId: Random.Shared.Next(1, CustomerCount),
33+
CustomerId: Random.Shared.Next(1, GetSeedConfig().CustomerCount),
3434
Offset: 0,
3535
Limit: Limit
3636
));
@@ -46,7 +46,7 @@ await ExecuteConcurrentlyAsync(QueriesToRun, ConcurrentQueries, async _ =>
4646
await using var dbContext = new SalesDbContext(_connectionString);
4747
var queries = new Queries(dbContext, useTracking: false);
4848
return await queries.GetCustomerOrders(new Queries.GetCustomerOrdersArgs(
49-
CustomerId: Random.Shared.Next(1, CustomerCount),
49+
CustomerId: Random.Shared.Next(1, GetSeedConfig().CustomerCount),
5050
Offset: 0,
5151
Limit: Limit
5252
));
@@ -62,7 +62,7 @@ await ExecuteConcurrentlyAsync(QueriesToRun, ConcurrentQueries, async _ =>
6262
await using var dbContext = new SalesDbContext(_connectionString);
6363
var queries = new Queries(dbContext, useTracking: true);
6464
return await queries.GetCustomerOrders(new Queries.GetCustomerOrdersArgs(
65-
CustomerId: Random.Shared.Next(1, CustomerCount),
65+
CustomerId: Random.Shared.Next(1, GetSeedConfig().CustomerCount),
6666
Offset: 0,
6767
Limit: Limit
6868
));
@@ -73,13 +73,8 @@ public static Func<Task> GetSeedMethod()
7373
{
7474
return async () =>
7575
{
76-
var seeder = new PostgresqlDatabaseSeeder(_connectionString);
77-
await seeder.SeedAsync(
78-
customerCount: 500, // with customer_id filter, this is 1/500 of the table returned
79-
productsPerCategory: 150,
80-
ordersPerCustomer: 1000,
81-
itemsPerOrder: 20 // 20 * 1000 = 20,000 possible rows returned
82-
);
76+
var seeder = new PostgresqlSeeder(_connectionString);
77+
await seeder.SeedAsync(GetSeedConfig());
8378
};
8479
}
8580
}

benchmark/BenchmarkRunner/Benchmarks/PostgresqlWriteBenchmark.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using BenchmarkDotNet.Configs;
33
using BenchmarkDotNet.Jobs;
44
using BenchmarkRunner.Utils;
5+
using Npgsql;
56
using PostgresEFCoreImpl;
67
using PostgresSqlcImpl;
78

@@ -19,10 +20,13 @@ public class PostgresqlWriteBenchmark : BaseWriteBenchmark
1920
private readonly Queries _efCoreImpl = new(new SalesDbContext(_connectionString), useTracking: false);
2021
private List<QuerySql.AddOrderItemsArgs> _testOrderItems = null!;
2122

23+
[Params(2_500_000)]
24+
public int TotalRecords { get; set; }
25+
2226
[BenchmarkCategory("Write")]
2327
[Benchmark(Baseline = true, Description = "SQLC - AddOrderItems")]
2428
[Arguments(500)]
25-
[Arguments(1000)]
29+
[Arguments(1_000)]
2630
public override async Task Sqlc_AddOrderItems(int batchSize)
2731
{
2832
await Helpers.InsertInBatchesAsync(_testOrderItems, batchSize, _sqlcImpl.AddOrderItemsAsync);
@@ -43,13 +47,8 @@ public static Func<Task> GetSeedMethod()
4347
{
4448
return async () =>
4549
{
46-
var seeder = new PostgresqlDatabaseSeeder(_connectionString);
47-
await seeder.SeedAsync(
48-
customerCount: 10,
49-
productsPerCategory: 15,
50-
ordersPerCustomer: 300,
51-
itemsPerOrder: 0
52-
);
50+
var seeder = new PostgresqlSeeder(_connectionString);
51+
await seeder.SeedAsync(GetSeedConfig());
5352
};
5453
}
5554

@@ -70,7 +69,15 @@ public async Task GlobalSetup()
7069
[IterationSetup]
7170
public static void IterationSetup()
7271
{
73-
PostgresqlDatabaseHelper.CleanupWriteTableAsync(_connectionString).GetAwaiter().GetResult();
72+
CleanupWriteTableAsync(_connectionString).GetAwaiter().GetResult();
7473
Helpers.InvokeGarbageCollection();
7574
}
75+
76+
private static async Task CleanupWriteTableAsync(string connectionString)
77+
{
78+
using var connection = new NpgsqlConnection(connectionString);
79+
await connection.OpenAsync();
80+
using var cmd = new NpgsqlCommand("TRUNCATE TABLE sales.order_items", connection);
81+
await cmd.ExecuteNonQueryAsync();
82+
}
7683
}

benchmark/BenchmarkRunner/Benchmarks/SqliteReadBenchmark.cs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class SqliteReadBenchmark : BaseReadBenchmark
1818
private static readonly string _connectionString = Config.GetSqliteConnectionString();
1919
private readonly QuerySql _sqlcImpl = new(_connectionString);
2020

21-
[Params(800)]
21+
[Params(1_000)]
2222
public int QueriesToRun { get; set; }
2323

2424
[Params(10, 25)]
@@ -31,7 +31,7 @@ public override async Task Sqlc_GetCustomerOrders()
3131
await ExecuteConcurrentlyAsync(QueriesToRun, ConcurrentQueries, _ =>
3232
{
3333
return _sqlcImpl.GetCustomerOrdersAsync(new QuerySql.GetCustomerOrdersArgs(
34-
CustomerId: Random.Shared.Next(1, CustomerCount),
34+
CustomerId: Random.Shared.Next(1, GetSeedConfig().CustomerCount),
3535
Offset: 0,
3636
Limit: Limit
3737
));
@@ -47,7 +47,7 @@ await ExecuteConcurrentlyAsync(QueriesToRun, ConcurrentQueries, async _ =>
4747
await using var dbContext = new SalesDbContext(_connectionString);
4848
var queries = new Queries(dbContext, useTracking: false);
4949
return await queries.GetCustomerOrders(new Queries.GetCustomerOrdersArgs(
50-
CustomerId: Random.Shared.Next(1, CustomerCount),
50+
CustomerId: Random.Shared.Next(1, GetSeedConfig().CustomerCount),
5151
Offset: 0,
5252
Limit: Limit
5353
));
@@ -63,7 +63,7 @@ await ExecuteConcurrentlyAsync(QueriesToRun, ConcurrentQueries, async _ =>
6363
await using var dbContext = new SalesDbContext(_connectionString);
6464
var queries = new Queries(dbContext, useTracking: true);
6565
return await queries.GetCustomerOrders(new Queries.GetCustomerOrdersArgs(
66-
CustomerId: Random.Shared.Next(1, CustomerCount),
66+
CustomerId: Random.Shared.Next(1, GetSeedConfig().CustomerCount),
6767
Offset: 0,
6868
Limit: Limit
6969
));
@@ -75,13 +75,8 @@ public static Func<Task> GetSeedMethod()
7575
return async () =>
7676
{
7777
EndToEndCommon.SetupBenchmarkSqliteDb();
78-
var seeder = new SqliteDatabaseSeeder(_connectionString);
79-
await seeder.SeedAsync(
80-
customerCount: 500, // with customer_id filter, this is 1/500 of the table returned
81-
productsPerCategory: 150,
82-
ordersPerCustomer: 500,
83-
itemsPerOrder: 10 // 10 * 500 = 5,000 possible rows returned
84-
);
78+
var seeder = new SqliteSeeder(_connectionString);
79+
await seeder.SeedAsync(GetSeedConfig());
8580
};
8681
}
8782
}

benchmark/BenchmarkRunner/Benchmarks/SqliteWriteBenchmark.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using BenchmarkDotNet.Jobs;
44
using BenchmarkRunner.Utils;
55
using EndToEndTests;
6+
using Microsoft.Data.Sqlite;
67
using SqliteEFCoreImpl;
78
using SqliteSqlcImpl;
89

@@ -20,6 +21,9 @@ public class SqliteWriteBenchmark : BaseWriteBenchmark
2021
private readonly Queries _efCoreImpl = new(new SalesDbContext(_connectionString), useTracking: false);
2122
private List<QuerySql.AddOrderItemsArgs> _testOrderItems = null!;
2223

24+
[Params(2_500_000)]
25+
public int TotalRecords { get; set; }
26+
2327
[BenchmarkCategory("Write")]
2428
[Benchmark(Baseline = true, Description = "SQLC - AddOrderItems")]
2529
[Arguments(50)]
@@ -45,13 +49,8 @@ public static Func<Task> GetSeedMethod()
4549
return async () =>
4650
{
4751
EndToEndCommon.SetupBenchmarkSqliteDb();
48-
var seeder = new SqliteDatabaseSeeder(_connectionString);
49-
await seeder.SeedAsync(
50-
customerCount: 10,
51-
productsPerCategory: 15,
52-
ordersPerCustomer: 300,
53-
itemsPerOrder: 0
54-
);
52+
var seeder = new SqliteSeeder(_connectionString);
53+
await seeder.SeedAsync(GetSeedConfig());
5554
};
5655
}
5756

@@ -70,9 +69,17 @@ public async Task GlobalSetup()
7069
}
7170

7271
[IterationSetup]
73-
public void IterationSetup()
72+
public static void IterationSetup()
7473
{
75-
SqliteDatabaseHelper.CleanupWriteTableAsync(_connectionString).GetAwaiter().GetResult();
74+
CleanupWriteTableAsync(_connectionString).GetAwaiter().GetResult();
7675
Helpers.InvokeGarbageCollection();
7776
}
77+
78+
private static async Task CleanupWriteTableAsync(string connectionString)
79+
{
80+
using var connection = new SqliteConnection(connectionString);
81+
await connection.OpenAsync();
82+
using var cmd = new SqliteCommand("DELETE FROM order_items", connection);
83+
await cmd.ExecuteNonQueryAsync();
84+
}
7885
}

0 commit comments

Comments
 (0)