diff --git a/BenchmarkService.cs b/BenchmarkService.cs index a32a5c8..c736d2b 100644 --- a/BenchmarkService.cs +++ b/BenchmarkService.cs @@ -11,20 +11,20 @@ namespace OptimizeMePlease { [MemoryDiagnoser] [HideColumns(BenchmarkDotNet.Columns.Column.Job, BenchmarkDotNet.Columns.Column.RatioSD, BenchmarkDotNet.Columns.Column.StdDev, BenchmarkDotNet.Columns.Column.AllocRatio)] - //[Config(typeof(Config))] + [Config(typeof(Config))] public class BenchmarkService { public BenchmarkService() { } - //private class Config : ManualConfig - //{ - // public Config() - // { - // SummaryStyle = BenchmarkDotNet.Reports.SummaryStyle.Default.WithRatioStyle(RatioStyle.Trend); - // } - //} + private class Config : ManualConfig + { + public Config() + { + SummaryStyle = BenchmarkDotNet.Reports.SummaryStyle.Default.WithRatioStyle(RatioStyle.Trend); + } + } /// /// Get top 2 Authors (FirstName, LastName, UserName, Email, Age, Country) @@ -32,7 +32,7 @@ public BenchmarkService() /// and all his/her books (Book Name/Title and Publishment Year) published before 1900 /// /// - [Benchmark] + [Benchmark(Baseline = true)] public List GetAuthors() { using var dbContext = new AppDbContext(); @@ -98,6 +98,45 @@ public List GetAuthors() return finalAuthors; } + // 1260x faster than GetAuthors() with this query + these indexes + // CREATE NONCLUSTERED INDEX idx_Books ON Books (AuthorId, Published) INCLUDE (Name) + // CREATE NONCLUSTERED INDEX idx_Author ON Authors (Age, BooksCount DESC) INCLUDE (Id, Country, UserId) + private static readonly Func> CompiledOptimized = + EF.CompileQuery((AppDbContext context) => context.Authors + .Where(x => x.Country == "Serbia" && x.Age == 27) + .OrderByDescending(x => x.BooksCount) + .Select(x => new AuthorDTO + { + UserFirstName = x.User.FirstName, + UserLastName = x.User.LastName, + UserEmail = x.User.Email, + UserName = x.User.UserName, + AuthorAge = x.Age, + AuthorCountry = x.Country, + AllBooks = x.Books.Where(b => b.Published.Year < 1900).Select(y => new BookDto + { + Name = y.Name, + Published = y.Published, + }).ToList() + }) + .Take(2)); + + /// + /// Get top 2 Authors (FirstName, LastName, UserName, Email, Age, Country) + /// from country Serbia aged 27, with the highest BooksCount + /// and all his/her books (Book Name/Title and Publishment Year) published before 1900 + /// + /// + [Benchmark] + public List GetAuthors_Optimized() + { + using var dbContext = new AppDbContext(); + + var authors = CompiledOptimized(dbContext).ToList(); + + return authors; + } + //[Benchmark] //public List GetAuthors_Optimized() //{ diff --git a/Context/AppDbContext.cs b/Context/AppDbContext.cs index dc14c8a..dd63e73 100644 --- a/Context/AppDbContext.cs +++ b/Context/AppDbContext.cs @@ -9,7 +9,9 @@ public class AppDbContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder options) { - options.UseSqlServer("Server=localhost;Database=OptimizeMePlease;Trusted_Connection=True;Integrated Security=true;MultipleActiveResultSets=true"); + options.UseSqlServer( + "Server=localhost,1433;Database=OptimizeMePlease;TrustServerCertificate=True;User Id=sa;Password=test@123;MultipleActiveResultSets=true") + /*.LogTo(s => { Console.WriteLine(s); }, LogLevel.Information)*/; } protected override void OnModelCreating(ModelBuilder modelBuilder) diff --git a/OptimizeMePlease.csproj b/OptimizeMePlease.csproj index f603ecd..15c4650 100644 --- a/OptimizeMePlease.csproj +++ b/OptimizeMePlease.csproj @@ -2,20 +2,20 @@ Exe - netcoreapp3.1 + net8.0 - + - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Program.cs b/Program.cs index c557a59..efbe192 100644 --- a/Program.cs +++ b/Program.cs @@ -24,9 +24,9 @@ public class Program static void Main(string[] args) { //Debugging - //BenchmarkService benchmarkService = new BenchmarkService(); - //var p = benchmarkService.GetAuthors_Optimized_Struct(); - //var d = benchmarkService.GetAuthors_Optimized_Struct1(); + BenchmarkService benchmarkService = new BenchmarkService(); + // var d = benchmarkService.GetAuthors(); + // var p = benchmarkService.GetAuthors_Optimized(); //Comment me after first execution, please. //IWillPopulateData(); @@ -36,7 +36,7 @@ static void Main(string[] args) public static void IWillPopulateData() { - string sqlConnectionString = @"Server=localhost;Database=OptimizeMePlease;Trusted_Connection=True;Integrated Security=true;MultipleActiveResultSets=true"; + string sqlConnectionString = @"Server=localhost,1433;Database=OptimizeMePlease;TrustServerCertificate=True;User Id=sa;Password=test@123;MultipleActiveResultSets=true"; string workingDirectory = Environment.CurrentDirectory; string path = Path.Combine(Directory.GetParent(workingDirectory).Parent.Parent.FullName, @"script.sql"); diff --git a/README.md b/README.md index 4982f83..677bc6f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # OptimizeMePlease +# Docker Compose + +- Run `docker-compose up -d` to start the database + ## You are probably here because you saw my post on Linkedin. ## Welcome! diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b39564d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +version: "3.9" + +services: + db: + image: "mcr.microsoft.com/mssql/server:2022-latest" + user: root + environment: + ACCEPT_EULA: "Y" + SA_PASSWORD: "test@123" + volumes: + - db_vol:/var/opt/mssql/data + ports: + - "1433:1433" + +volumes: + db_vol: {} \ No newline at end of file