Below question arose in my head when refactoring complex stored procedure that was a bottleneck in my database... Let me introduce to the topic. Suppose we have lookup/dictionary table like (it contains GUID as Foreign Key to other tables and name which is human readable):
CREATE TABLE [dbo].[PlayerStatus](
[PlayerStatusId] [uniqueidentifier] NOT NULL,
[PlayerStatusName] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_PlayerStatus] PRIMARY KEY CLUSTERED
(
[PlayerStatusId] ASC
))
and there's a Player table :
CREATE TABLE [dbo].[Player](
[PlayerId] [uniqueidentifier] NOT NULL,
[PlayerStatusId] [uniqueidentifier] NOT NULL,
[PlayerName] [nchar](10) NOT NULL,
[PlayerSurname] [nchar](10) NOT NULL,
CONSTRAINT [PK_Player] PRIMARY KEY CLUSTERED ( [PlayerId] ASC )) ON [PRIMARY]
Pretty sraightforward.
Let's say that somewhere in the code there's huge query that accesses a great deal of tables:
SELECT ...
FROM Player JOIN PlayerStatus ON Player.PlayerStatusId = PlayerStatus.PlayerStatusId
.....
WHERE PlayerStatus.PlayerStatusName = 'Active' ....
Now, in my stored procedure, according to execution plan Players table was included in resultset at the beginning. Assuing that this is very large table with milions of rows, hash join between Player and PlayerStatus could be time consuming. By optimizing this query I could rewrite it to someting like this
SELECT ...
FROM Player .....
WHERE PlayerStatus.PlayerStatusId = '46bb6a12-4cd9-4b6c-84c2-7444f5f45eb6' ....
And that's exactly what I did in my bottleneck procedure. That way, I removed 4 similar lookup/dictionary tables that contained different type of statuses. To my suprise, I managed to improve performance by 50%, even though I thought that such tables won't impact performance at all. But that's side plot. My question is: what do you thing of hardcoding guids?
EDIT
- I do have PK indexes on PlayerStatus.PlayerStatusId and Player.PlayerId
- I do have FK constraint on Player.PlayerStatusId:
ALTER TABLE [dbo].[Player] WITH CHECK ADD CONSTRAINT [FK_Player_PlayerStatus] FOREIGN KEY([PlayerStatusId]) REFERENCES [dbo].[PlayerStatus] ([PlayerStatusId])
- Player table constains about 2mln records, PlayerStatus table contains about 25 records