C# / . NET Core
Dependencies
Code
using System;using System.Collections.Generic;using System.Data;using System.Diagnostics;using System.Threading;using System.Threading.Tasks;using SingleStoreConnector;namespace SingleStoreDBTest{public class SingleStoreDBTest{/*** Tweak the following globals to fit your environment* ###################################################*/public const string HOST = "127.0.0.1";public const int PORT = 3306;public const string USER = "root";public const string PASSWORD = "passkey";// Specify which database and table to work with.// Note: this database will be dropped at the end of this scriptpublic const string DATABASE = "test";public const string TABLE = "tbl";// The number of workers to runpublic const int NUM_WORKERS = 20;// Run the workload for this many secondspublic const int WORKLOAD_TIME = 10; // seconds// Batch size to usepublic const int BATCH_SIZE = 5000;/*** Internal code starts here* #########################*/private IDbCommand dbCommand;private string insertCommand;private void GetDbCommand(){IDbConnection conn = new SingleStoreConnection();conn.ConnectionString = $"Server={HOST};Port={PORT};Uid={USER};Pwd={PASSWORD};";conn.Open();dbCommand = conn.CreateCommand();string[] _batch = new string[BATCH_SIZE];Array.Fill(_batch, "(DEFAULT)");insertCommand = $"INSERT INTO {TABLE} VALUES {string.Join(",", _batch)}";}private void SetupTestDb(){dbCommand.CommandText = $"CREATE DATABASE IF NOT EXISTS {DATABASE}";dbCommand.ExecuteNonQuery();dbCommand.CommandText = $"USE {DATABASE}";dbCommand.ExecuteNonQuery();dbCommand.CommandText = $"CREATE TABLE {TABLE} (id int primary key auto_increment)";dbCommand.ExecuteNonQuery();}private void Warmup(){Console.WriteLine("Warming up workload");dbCommand.CommandText = insertCommand;dbCommand.ExecuteNonQuery(); // FRAGILE: included in count, not included in time}private void DoBenchmark(){Console.WriteLine($"Launching {NUM_WORKERS} workers for {WORKLOAD_TIME} sec");Thread[] workers = new Thread[NUM_WORKERS];for(int i = 0; i < NUM_WORKERS; i++){workers[i] = new Thread(new ThreadStart(Worker));workers[i].Start();}Console.WriteLine($"{workers.Length} workers running...");for(int i = 0; i < NUM_WORKERS; i++){workers[i].Join();}}private void Worker(){// Create another connection per threadusing (IDbConnection conn = new SingleStoreConnection()){conn.ConnectionString = $"Server={HOST};Port={PORT};database={DATABASE};Uid={USER};Pwd={PASSWORD};SslMode=None;";conn.Open();using (IDbCommand dbCommand = conn.CreateCommand()){dbCommand.CommandText = insertCommand;Stopwatch stop = new Stopwatch();stop.Start();while(stop.ElapsedMilliseconds < WORKLOAD_TIME*1000){dbCommand.ExecuteNonQuery();}}}}private void ShowStats(){dbCommand.CommandText = $"USE {DATABASE}";dbCommand.ExecuteNonQuery();dbCommand.CommandText = $"SELECT COUNT(*) FROM {TABLE}";using (IDataReader reader = dbCommand.ExecuteReader()){long count = 0;while(reader.Read()){count = (long)reader["COUNT(*)"];}Console.WriteLine($"{count} rows inserted using {NUM_WORKERS} workers");Console.WriteLine($"{count / WORKLOAD_TIME} rows per second");}}private void CleanupTestDb(){if (dbCommand != null){Console.WriteLine("Cleaning up");dbCommand.CommandText = $"USE `information_schema`";dbCommand.ExecuteNonQuery();dbCommand.CommandText = $"DROP DATABASE IF EXISTS {DATABASE}";dbCommand.ExecuteNonQuery();dbCommand = null;}}public static int Main(string[] args){SingleStoreDBTest tester = new SingleStoreDBTest();try{tester.GetDbCommand();tester.SetupTestDb();tester.Warmup();tester.DoBenchmark();tester.ShowStats();tester.CleanupTestDb();return 0;}catch (Exception ex){Console.WriteLine($"ERROR: {ex.Message}, {ex.GetType()}, {ex.StackTrace}");try{tester.CleanupTestDb();}catch{// ignore error}return 1;}}}}
Last modified: September 7, 2023