C
C#4w ago
Leandro

refactor database to stop using UNIQUEIDENTIFIER as PK

So I didn't know enough of databases to know that it is not a good idea to use uniqueidentifiers as PK in MSSQL database. Now that I have a lot of records my queries are starting to become slow. I'm using Entity Framework. What steps should I take to migrate my database to INT PK bearing in mind all the relationships between tables that already exists? I can't loose the relationships. I would still have a column like, "referenceKey" that I would use to access specific records in my database so I can prevent the guessing PK attack. But having INT as PK would allow me to create more efficient indices and whatnot, right? Has anyone ever done such a thing? How should I proceed?
34 Replies
Mayor McCheese
What makes you think using integer instead of guid is going to be faster? It can be faster. But have you done any analysis to determine it will be faster? What is a lot of records?
Yawnder
Yawnder4w ago
Also, how are they generated? By the database or by the code?
Leandro
LeandroOP4w ago
GUID's are generated by the database when record is inserted. I do not generate them by the code. For example, I have this table with 303 records. Table name is GenericFields. Query is taking 25 seconds to complete. IIRC, I'm running RDS in small or micro instance, it's the smallest one. Table has 303 records.
Leandro
LeandroOP4w ago
Here is the EF query log
No description
Leandro
LeandroOP4w ago
303 is not a lot of records, so no clue why it took so long.
Yawnder
Yawnder4w ago
Oh, that has nothing to do with PKs then I'd guess a non-indexed column, but even so. I have to go for now though, sorry.
Leandro
LeandroOP4w ago
No problem. GPT told me to do something about indexes like this
Leandro
LeandroOP4w ago
No description
Leandro
LeandroOP4w ago
but I'm not sure. I replaced another paginated query to use 100% dapper and I added "Covering Indexes" and it still take 4seconds to query Query: SELECT Id, StatusEnum, Descricao, StartDate, EndDate, CreationTime, ReportType FROM RelatoriosPdf WHERE CompanyId = @CompanyId ORDER BY CreationTime OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY Index: CREATE INDEX IX_RelatoriosPdf_CompanyId_CreationTime ON RelatoriosPdf (CompanyId, CreationTime) INCLUDE (Id, StatusEnum, Descricao, StartDate, EndDate, ReportType); it seems to not have speed up anything
Leandro
LeandroOP4w ago
In execution planner, it seems to search only the index.
No description
Leandro
LeandroOP4w ago
this is another query that I tried to optmize. In SSMS query runs in less than one second, but when called from frontend and everything else, takes more than 4segs and I'm not really doing anything fancy in C# to add such time except using Mapster to map the sql result to DTO and give it back to frontend. the sql performance seems to have degraded over time. One time when I refactored all the queries, it wasn't taking 3ms to run them all. Now the same batch takes more than 20secs to run. Maybe if I restart RDS time will go back to normal. Maybe the RDS instance is too small? This is driving me crazy with all sorts of problems in production. Any help would he heavily appreciated these are other queries unrelated to the ones I posted here, but it's funny how one time they go fast and all of a sudden it starts to become slow
Mayor McCheese
How wide are the tables?
Thalnos
Thalnos4w ago
I go with @Yawnder - [▰/▱] your db is probably missing indexing here Check the execution on db side
Thalnos
Thalnos4w ago
Analyze an actual execution plan - SQL Server
Learn how to analyze actual graphical execution plans, which contain runtime information, by using SQL Server Management Studio Plan Analysis feature.
Thalnos
Thalnos4w ago
When it takes long on the „index seek“ part you are missing an index
Mayor McCheese
They only have 303 rows though, I agree indexes are good for read, but something else is going on https://discord.com/channels/143867839282020352/1338019303382843432/1338032815220199465 do i spy eav?
MODiX
MODiX4w ago
Leandro
GUID's are generated by the database when record is inserted. I do not generate them by the code. For example, I have this table with 303 records. Table name is GenericFields. Query is taking 25 seconds to complete. IIRC, I'm running RDS in small or micro instance, it's the smallest one. Table has 303 records.
React with ❌ to remove this embed.
Leandro
LeandroOP4w ago
sorry, I dont understand
Mayor McCheese
Eav is a database design tool anti pattern, looking at the columns in your query, you have one called content, and your table is called GenericFields
Mayor McCheese
Medium
Entity Attribute Value Model
Today, we are going to talk about a Database design model, known as the Entity Attribute Value model aka EAV model. EAV Database models are…
Mayor McCheese
Are you doing something like this? Regardless, circling back to your initial question, I have doubts that restriping your tables to users int is going to give you much gain. It seems like you've got other problems potentially going on.
Leandro
LeandroOP4w ago
I dont think so, content column is a json string
Mayor McCheese
oic that avoids the need for eav tbh
Leandro
LeandroOP4w ago
I think Hangfire was degrading performance. After I disabled it, some queries are running faster now. Maybe I'll look for a different solution. SQL Profiler was very active before I disabled yeah, it was definately hangfire. I make like 15 queries to gather data to build a PDF report. Before it could take as long as 20secs. Now with Hangffire disabled, everything ran in less than 2 seconds. Well, I was already warned that this lib is harsh on database. Maybe some obscure configuration to make it less of a bottleneck.. Will have to study more
Mayor McCheese
Maybe use mass transit?
Leandro
LeandroOP4w ago
I was thinking a out lambda and event bridges? But I will check this for sure
Leandro
LeandroOP4w ago
it still needs Hangfire. Sad
No description
Mayor McCheese
How many jobs do you have? I'm inferring just one?
Leandro
LeandroOP4w ago
a couple, 5 or 6 . They don't run everytime but still it completely disgraced my database xD maybe there is some obscure pooling settings in hangfire or something.. but I'm considering just removing this crazy lib and try to do with lambdas and event bridges
Mayor McCheese
Can you use another db for hangfire or switch to quartz?
Leandro
LeandroOP4w ago
unfortunately I cannot, my budget is very low. Quartz still needs a db right? It might be worth a shot to try but I'm inclined to think that a solution with 0 database usage would be better
Mayor McCheese
No You can use a database You don't have to
wasabi
wasabi3w ago
You do however need to use somethig for permanent storage.
Mayor McCheese
There's a memory provider iirc I don't know what the budget here is Memory storage only works in the simplest cases

Did you find this page helpful?