From 8f79c06344b1db8cdef625b8692e17d5a1ff2d0c Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Wed, 20 Oct 2021 17:33:42 +0000 Subject: [PATCH] performance, index tuning etc --- .vscode/launch.json | 2 +- server/AyaNova/biz/EventLogProcessor.cs | 2 - server/AyaNova/biz/UnitBiz.cs | 2 +- server/AyaNova/util/AySchema.cs | 13 +++- server/AyaNova/util/Seeder.cs | 90 ++++++++++++------------- 5 files changed, 57 insertions(+), 52 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c74c1699..b535d320 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -53,7 +53,7 @@ "AYANOVA_FOLDER_BACKUP_FILES": "c:\\temp\\RavenTestData\\backupfiles", "AYANOVA_FOLDER_TEMPORARY_SERVER_FILES": "c:\\temp\\RavenTestData\\tempfiles", "AYANOVA_SERVER_TEST_MODE": "true", - "AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "small", + "AYANOVA_SERVER_TEST_MODE_SEEDLEVEL": "medium", "AYANOVA_SERVER_TEST_MODE_TZ_OFFSET": "-7", "AYANOVA_BACKUP_PG_DUMP_PATH": "C:\\data\\code\\postgres_14\\bin\\" }, diff --git a/server/AyaNova/biz/EventLogProcessor.cs b/server/AyaNova/biz/EventLogProcessor.cs index a7e31bd6..50b374e0 100644 --- a/server/AyaNova/biz/EventLogProcessor.cs +++ b/server/AyaNova/biz/EventLogProcessor.cs @@ -20,8 +20,6 @@ namespace AyaNova.Biz /// internal static async Task LogEventToDatabaseAsync(Event newEvent, AyContext ct) { - //System.Diagnostics.Debug.WriteLine($"Event log event for {newEvent.AyId}:{newEvent.AyaType} {newEvent.AyEvent} {newEvent.Created}"); - await ct.Event.AddAsync(newEvent); await ct.SaveChangesAsync(); } diff --git a/server/AyaNova/biz/UnitBiz.cs b/server/AyaNova/biz/UnitBiz.cs index e7730bc4..e8d6321b 100644 --- a/server/AyaNova/biz/UnitBiz.cs +++ b/server/AyaNova/biz/UnitBiz.cs @@ -217,7 +217,7 @@ namespace AyaNova.Biz //(two different manufacturers products could have the same serial easily, but it's less likely for two different units of the same unitmodel) // if (!PropertyHasErrors("Serial")) - { + { //Use Any command is efficient way to check existance, it doesn't return the record, just a true or false if (await ct.Unit.AnyAsync(z => z.Serial == proposedObj.Serial && z.UnitModelId == proposedObj.UnitModelId && z.Id != proposedObj.Id)) { diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index 64508d46..99fe287a 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -23,7 +23,7 @@ namespace AyaNova.Util private const int DESIRED_SCHEMA_LEVEL = 1; internal const long EXPECTED_COLUMN_COUNT = 1300; - internal const long EXPECTED_INDEX_COUNT = 146; + internal const long EXPECTED_INDEX_COUNT = 150; internal const long EXPECTED_CHECK_CONSTRAINTS = 517; internal const long EXPECTED_FOREIGN_KEY_CONSTRAINTS = 193; internal const long EXPECTED_VIEWS = 11; @@ -31,7 +31,7 @@ namespace AyaNova.Util //!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImportingAsync WHEN NEW TABLES ADDED!!!! - ///////////////////////////////////////////////////////////////// C1300:I146:CC517:FC193:V11:R2 + ///////////////////////////////////////////////////////////////// C1300:I148:CC517:FC193:V11:R2 @@ -752,6 +752,15 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); + "CONSTRAINT chk_contract_valid CHECK((contractid IS NULL) OR (contractid IS NOT NULL AND contractexpires IS NOT NULL)) " + " )"); + //indexes to speed up deletion + await ExecQueryAsync("CREATE INDEX idx_aunit_parentunitid ON aunit(parentunitid ASC NULLS LAST)"); + await ExecQueryAsync("CREATE INDEX idx_aunit_replacedbyunitid ON aunit(replacedbyunitid ASC NULLS LAST)"); + + //indexes to speed up creation (validation) + await ExecQueryAsync("CREATE INDEX idx_aunit_serial ON aunit(serial)"); + await ExecQueryAsync("CREATE INDEX idx_aunit_modelid ON aunit (unitmodelid ASC NULLS LAST)"); + + //LOANUNIT await ExecQueryAsync("CREATE TABLE aloanunit (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT NOT NULL UNIQUE, active BOOL NOT NULL, " + "notes TEXT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY, " diff --git a/server/AyaNova/util/Seeder.cs b/server/AyaNova/util/Seeder.cs index 31ec3641..e0615697 100644 --- a/server/AyaNova/util/Seeder.cs +++ b/server/AyaNova/util/Seeder.cs @@ -925,7 +925,7 @@ namespace AyaNova.Util ///////////////////////////////////////////////////// //Seed some test memos { - for (int x = 0; x < 200; x++) + for (int x = 0; x < 50; x++) { Memo memo = new Memo(); memo.Name = Fake.Lorem.Sentence(); @@ -1525,7 +1525,7 @@ namespace AyaNova.Util TaskGroup t = new TaskGroup(); t.Name = "Clean and inspect Class 7C"; t.Active = true; - t.Notes = Fake.Lorem.Sentence(); + t.Notes = Fake.Lorem.Sentence(null,3); t.Items.Add(new TaskGroupItem() { Sequence = 1, Task = "Open unit" }); t.Items.Add(new TaskGroupItem() { Sequence = 2, Task = "Test tinclavic seals" }); t.Items.Add(new TaskGroupItem() { Sequence = 3, Task = "Inspect triple-bonded polysium for cracks" }); @@ -1552,7 +1552,7 @@ namespace AyaNova.Util TaskGroup t = new TaskGroup(); t.Name = "Aerostat monitor standard refurb"; t.Active = true; - t.Notes = Fake.Lorem.Sentence(); + t.Notes = Fake.Lorem.Sentence(null,3); t.Items.Add(new TaskGroupItem() { Sequence = 1, Task = "Power down unit" }); t.Items.Add(new TaskGroupItem() { Sequence = 2, Task = "Open seals" }); t.Items.Add(new TaskGroupItem() { Sequence = 3, Task = "Replace central core" }); @@ -1759,7 +1759,7 @@ namespace AyaNova.Util u.Roles = roles; u.UserType = userType; u.EmployeeNumber = "A-" + (454 + TotalSeededUsers + x).ToString() + "-Y"; - u.Notes = Fake.Lorem.Sentence(null, 5);//Fake.Lorem.Paragraph(2); + u.Notes = Fake.Lorem.Sentence(null, 3);//Fake.Lorem.Paragraph(2); //TODO: After have USER and HEADOFFICE and VENDOR, if usertype is subcontractor or client or headoffice it needs to set a corresponding user's parent org record id to go with it //use provided tags or generate them if (tags == null) @@ -1878,14 +1878,12 @@ namespace AyaNova.Util switch (slevel) { case Level.SeedLevel.Small: + case Level.SeedLevel.Medium: await SeedUnitAsync(log, 2, NewObject.Id); break; case Level.SeedLevel.Large: - case Level.SeedLevel.Medium: - await SeedUnitAsync(log, 5, NewObject.Id); - break; case Level.SeedLevel.Huge: - await SeedUnitAsync(log, 10, NewObject.Id); + await SeedUnitAsync(log, 5, NewObject.Id); break; } } @@ -2032,7 +2030,7 @@ namespace AyaNova.Util } while (!HashProjectNames.Add(o.Name)); o.AccountNumber = Fake.Finance.Account(); o.Active = true; - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,3); o.Tags = RandomTags(); DateTime dtSeed = Fake.Date.Between(seedStartWindow, seedEndWindow).ToUniversalTime(); o.DateStarted = dtSeed; @@ -2083,7 +2081,7 @@ namespace AyaNova.Util } while (!HashRateNames.Add(o.Name)); o.AccountNumber = Fake.Finance.Account(); o.Active = true; - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,3); o.Tags = RandomTags(); o.Cost = Fake.Random.Decimal(0.25m, 50); @@ -2133,7 +2131,7 @@ namespace AyaNova.Util } while (!HashRateNames.Add(o.Name)); o.AccountNumber = Fake.Finance.Account(); o.Active = true; - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,3); o.Tags = RandomTags(); o.Cost = Fake.Random.Decimal(0.25m, 10); @@ -2184,7 +2182,7 @@ namespace AyaNova.Util o.Active = true; - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,3); o.Tags = RandomTags(); o.VendorId = Fake.Random.Long(1, TotalSeededVendors);//random picks in range Inclusive but sql id's start at 1 so this is kosher (not zero based) o.UPC = Fake.Commerce.Ean13(); @@ -2236,7 +2234,7 @@ namespace AyaNova.Util } while (!HashUnitNames.Add(o.Serial)); o.Active = true; - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,3); o.Tags = RandomTags(); //Override model warranty 5% chance (1/20) if (Fake.Random.Number(1, 20) == 5) @@ -2345,7 +2343,7 @@ namespace AyaNova.Util //o.UnitId is shadow unit o.Active = true; - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,3); o.Tags = RandomTags(); o.RateHour = Fake.Random.Decimal(1, 25); @@ -2426,7 +2424,7 @@ namespace AyaNova.Util CustomerServiceRequest o = new CustomerServiceRequest(); o.Name = Fake.Hacker.Phrase(); - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,8); o.Tags = RandomTags(); o.DateRequested = Fake.Date.Between(seedStartWindow, seedEndWindow).ToUniversalTime(); o.CustomerId = GetRandomCustomerId();//Fake.Random.Long(1, TotalSeededCustomers); @@ -2466,7 +2464,7 @@ namespace AyaNova.Util } while (!HashPartWarehouseNames.Add(o.Name)); o.Active = true; - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,3); o.Tags = RandomTags(); @@ -2509,7 +2507,7 @@ namespace AyaNova.Util } while (!HashPartNumbers.Add(o.PartNumber)); o.Active = true; - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,3); o.Tags = RandomTags(); o.ManufacturerId = Fake.Random.Long(1, 3);//There are minimum 10 vendors seeded, want parts all in the first few so that some po stuff can kick in (vendorpartnumber etc) o.ManufacturerNumber = "man-" + o.PartNumber; @@ -2614,7 +2612,7 @@ namespace AyaNova.Util } while (!HashPartAssemblyNames.Add(o.Name)); o.Active = true; - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,3); o.Tags = RandomTags(); int partCount = Fake.Random.Int(2, 5); for (int y = 0; y < partCount; y++) @@ -2657,7 +2655,7 @@ namespace AyaNova.Util for (int x = 0; x < count; x++) { PurchaseOrder o = new PurchaseOrder(); - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,3); o.Tags = RandomTags(); o.VendorId = Fake.Random.Long(1, 9);//this matches the range set in parts so that we get ALL vendor numbers being set var poDate = Fake.Date.Between(seedStartWindow, seedEndWindow); @@ -2665,12 +2663,12 @@ namespace AyaNova.Util o.ExpectedReceiveDate = poDate.AddDays(5).ToUniversalTime(); o.ReferenceNumber = Fake.Finance.Account(6); - o.VendorMemo = Fake.Lorem.Sentence(); + o.VendorMemo = Fake.Lorem.Sentence(null,3); if (Fake.Random.Number(1, 10) == 5) o.ProjectId = Fake.Random.Long(1, TotalSeededProjects); - o.Text1 = Fake.Lorem.Sentence(1, 3); - o.Text2 = Fake.Lorem.Sentence(1, 3); + o.Text1 = Fake.Lorem.Sentence(null, 3); + o.Text2 = Fake.Lorem.Sentence(null, 3); List partsAdded = new List(); int partCount = Fake.Random.Int(1, 5); @@ -2798,7 +2796,7 @@ namespace AyaNova.Util for (int x = 0; x < count; x++) { WorkOrder o = new WorkOrder(); - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,6); o.Tags = RandomTags(); if (Fake.Random.Bool())//50% have projects o.ProjectId = Fake.Random.Long(1, TotalSeededProjects); @@ -2867,7 +2865,7 @@ namespace AyaNova.Util var woItemUnit = new WorkOrderItemUnit() { UnitId = GetRandomUnitForCustomer(o.CustomerId), - Notes = Fake.Lorem.Sentence(3) + Notes = Fake.Lorem.Sentence(null,3) }; woItem.Units.Add(woItemUnit); } @@ -3039,7 +3037,7 @@ namespace AyaNova.Util ServiceStartDate = woDate, ServiceStopDate = woDate.AddHours(1), ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates), - ServiceDetails = Fake.Lorem.Sentence() + ServiceDetails = Fake.Lorem.Sentence(null,6) }; woItem.Labors.Add(woItemLabor); if (Fake.Random.Bool())//50% @@ -3051,7 +3049,7 @@ namespace AyaNova.Util ServiceStartDate = woDate, ServiceStopDate = woDate.AddHours(1), ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates), - ServiceDetails = Fake.Lorem.Sentence() + ServiceDetails = Fake.Lorem.Sentence(null,6) }; woItem.Labors.Add(woItemLabor); } @@ -3067,7 +3065,7 @@ namespace AyaNova.Util TravelStartDate = woDate, TravelStopDate = woDate.AddHours(1), TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates), - TravelDetails = Fake.Lorem.Sentence(), + TravelDetails = Fake.Lorem.Sentence(null,3), Distance = Fake.Random.Int(1, 20) }; woItem.Travels.Add(woItemTravel); @@ -3170,7 +3168,7 @@ namespace AyaNova.Util var woItemOutsideService = new WorkOrderItemOutsideService() { UnitId = GetRandomUnitForCustomer(o.CustomerId), - Notes = Fake.Lorem.Sentence(), + Notes = Fake.Lorem.Sentence(null,3), VendorSentToId = Fake.Random.Long(1, TotalSeededVendors), VendorSentViaId = Fake.Random.Long(1, TotalSeededVendors), RMANumber = "RMA" + Fake.Finance.Account(6), @@ -3341,7 +3339,7 @@ namespace AyaNova.Util for (int x = 0; x < count; x++) { Quote o = new Quote(); - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,6); o.Tags = RandomTags(); if (Fake.Random.Bool())//50% have projects o.ProjectId = Fake.Random.Long(1, TotalSeededProjects); @@ -3407,14 +3405,14 @@ namespace AyaNova.Util var woItemUnit = new QuoteItemUnit() { UnitId = GetRandomUnitForCustomer(o.CustomerId), - Notes = Fake.Lorem.Sentence() + Notes = Fake.Lorem.Sentence(null,3) }; woItem.Units.Add(woItemUnit); woItemUnit = new QuoteItemUnit() { UnitId = GetRandomUnitForCustomer(o.CustomerId), - Notes = Fake.Lorem.Sentence() + Notes = Fake.Lorem.Sentence(null,3) }; woItem.Units.Add(woItemUnit); @@ -3534,7 +3532,7 @@ namespace AyaNova.Util ServiceStartDate = woDate, ServiceStopDate = woDate.AddHours(1), ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates), - ServiceDetails = Fake.Lorem.Sentence() + ServiceDetails = Fake.Lorem.Sentence(null,3) }; woItem.Labors.Add(woItemLabor); @@ -3545,7 +3543,7 @@ namespace AyaNova.Util ServiceStartDate = woDate, ServiceStopDate = woDate.AddHours(1), ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates), - ServiceDetails = Fake.Lorem.Sentence() + ServiceDetails = Fake.Lorem.Sentence(null,3) }; woItem.Labors.Add(woItemLabor); @@ -3558,7 +3556,7 @@ namespace AyaNova.Util TravelStartDate = woDate, TravelStopDate = woDate.AddHours(1), TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates), - TravelDetails = Fake.Lorem.Sentence(), + TravelDetails = Fake.Lorem.Sentence(null,3), Distance = Fake.Random.Int(1, 20) }; woItem.Travels.Add(woItemTravel); @@ -3570,7 +3568,7 @@ namespace AyaNova.Util TravelStartDate = woDate, TravelStopDate = woDate.AddHours(1), TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates), - TravelDetails = Fake.Lorem.Sentence(), + TravelDetails = Fake.Lorem.Sentence(null,3), Distance = Fake.Random.Int(1, 20) }; woItem.Travels.Add(woItemTravel); @@ -3660,7 +3658,7 @@ namespace AyaNova.Util var woItemOutsideService = new QuoteItemOutsideService() { UnitId = GetRandomUnitForCustomer(o.CustomerId), - Notes = Fake.Lorem.Sentence(), + Notes = Fake.Lorem.Sentence(null,3), VendorSentToId = Fake.Random.Long(1, TotalSeededVendors), VendorSentViaId = Fake.Random.Long(1, TotalSeededVendors), RMANumber = "RMA" + Fake.Finance.Account(6), @@ -3681,7 +3679,7 @@ namespace AyaNova.Util woItemOutsideService = new QuoteItemOutsideService() { UnitId = GetRandomUnitForCustomer(o.CustomerId), - Notes = Fake.Lorem.Sentence(), + Notes = Fake.Lorem.Sentence(null,3), VendorSentToId = Fake.Random.Long(1, TotalSeededVendors), VendorSentViaId = Fake.Random.Long(1, TotalSeededVendors), RMANumber = "RMA" + Fake.Finance.Account(6), @@ -3757,7 +3755,7 @@ namespace AyaNova.Util for (int x = 0; x < count; x++) { PM o = new PM(); - o.Notes = Fake.Lorem.Sentence(); + o.Notes = Fake.Lorem.Sentence(null,3); o.Tags = RandomTags(); if (Fake.Random.Bool())//50% have projects o.ProjectId = Fake.Random.Long(1, TotalSeededProjects); @@ -3836,14 +3834,14 @@ namespace AyaNova.Util var woItemUnit = new PMItemUnit() { UnitId = GetRandomUnitForCustomer(o.CustomerId), - Notes = Fake.Lorem.Sentence() + Notes = Fake.Lorem.Sentence(null,3) }; woItem.Units.Add(woItemUnit); woItemUnit = new PMItemUnit() { UnitId = GetRandomUnitForCustomer(o.CustomerId), - Notes = Fake.Lorem.Sentence() + Notes = Fake.Lorem.Sentence(null,3) }; woItem.Units.Add(woItemUnit); @@ -3963,7 +3961,7 @@ namespace AyaNova.Util ServiceStartDate = woDate, ServiceStopDate = woDate.AddHours(1), ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates), - ServiceDetails = Fake.Lorem.Sentence() + ServiceDetails = Fake.Lorem.Sentence(null,3) }; woItem.Labors.Add(woItemLabor); @@ -3974,7 +3972,7 @@ namespace AyaNova.Util ServiceStartDate = woDate, ServiceStopDate = woDate.AddHours(1), ServiceRateId = Fake.Random.Long(1, TotalSeededServiceRates), - ServiceDetails = Fake.Lorem.Sentence() + ServiceDetails = Fake.Lorem.Sentence(null,3) }; woItem.Labors.Add(woItemLabor); @@ -3987,7 +3985,7 @@ namespace AyaNova.Util TravelStartDate = woDate, TravelStopDate = woDate.AddHours(1), TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates), - TravelDetails = Fake.Lorem.Sentence(), + TravelDetails = Fake.Lorem.Sentence(null,3), Distance = Fake.Random.Int(1, 20) }; woItem.Travels.Add(woItemTravel); @@ -3999,7 +3997,7 @@ namespace AyaNova.Util TravelStartDate = woDate, TravelStopDate = woDate.AddHours(1), TravelRateId = Fake.Random.Long(1, TotalSeededTravelRates), - TravelDetails = Fake.Lorem.Sentence(), + TravelDetails = Fake.Lorem.Sentence(null,3), Distance = Fake.Random.Int(1, 20) }; woItem.Travels.Add(woItemTravel); @@ -4089,7 +4087,7 @@ namespace AyaNova.Util var woItemOutsideService = new PMItemOutsideService() { UnitId = GetRandomUnitForCustomer(o.CustomerId), - Notes = Fake.Lorem.Sentence(), + Notes = Fake.Lorem.Sentence(null,3), VendorSentToId = Fake.Random.Long(1, TotalSeededVendors), VendorSentViaId = Fake.Random.Long(1, TotalSeededVendors), RMANumber = "RMA" + Fake.Finance.Account(6), @@ -4110,7 +4108,7 @@ namespace AyaNova.Util woItemOutsideService = new PMItemOutsideService() { UnitId = GetRandomUnitForCustomer(o.CustomerId), - Notes = Fake.Lorem.Sentence(), + Notes = Fake.Lorem.Sentence(null,3), VendorSentToId = Fake.Random.Long(1, TotalSeededVendors), VendorSentViaId = Fake.Random.Long(1, TotalSeededVendors), RMANumber = "RMA" + Fake.Finance.Account(6),