Using: SQL Server 2016+
I've been looking to see if there is any way to evaluate how long it takes SQL Server to recompile the execution plan for a query. We have several stored procedures where we select from table 1 based on a nullable parameter in table 2. E.g. If customer is not null return their sales else return all sales.
Sample data:
DROP TABLE IF EXISTS dbo.TestTable1;
DROP TABLE IF EXISTS dbo.TestTable2;
CREATE TABLE dbo.TestTable1 (ID INT NOT NULL PRIMARY KEY CLUSTERED , TextValue NVARCHAR(255) NULL);
CREATE TABLE dbo.TestTable2 (ID INT NOT NULL PRIMARY KEY CLUSTERED , TextValue NVARCHAR(255) NULL);
INSERT INTO TestTable1 (ID, TextValue)
VALUES (1, N'Table 1 - Text 1'),
(2, N'Table 1 - Text 2'),
(3, N'Table 1 - Text 3'),
(4, N'Table 1 - Text 4'),
(5, N'Table 1 - Text 5'),
(6, N'Table 1 - Text 6'),
(7, N'Table 1 - Text 7'),
(8, N'Table 1 - Text 8'),
(9, N'Table 1 - Text 9'),
(10, N'Table 1 - Text 10');
INSERT INTO TestTable2 (ID, TextValue)
VALUES (1, N'Table 2 - Text 1'),
(2, N'Table 2 - Text 2'),
(3, N'Table 2 - Text 3'),
(4, N'Table 2 - Text 4'),
(5, N'Table 2 - Text 5'),
(6, N'Table 2 - Text 6'),
(7, N'Table 2 - Text 7'),
(8, N'Table 2 - Text 8'),
(9, N'Table 2 - Text 9'),
(10, N'Table 2 - Text 10');
This is greatly over simplified as we would have multiple possible conditions, linking to multiple tables. We are currently looking at recompiling the query so that the joins to the secondary table are only made when required.
DECLARE @LookupValue NVARCHAR(50);
SET @LookupValue = NULL;
SELECT *
FROM dbo.TestTable1 T1
WHERE @LookupValue IS NULL
OR EXISTS ( SELECT TOP (1) 1 A FROM dbo.TestTable2 T2 WHERE T1.ID = T2.ID AND T2.TextValue = @LookupValue)
OPTION (RECOMPILE)
SET @LookupValue = N'Table 2 - Text 1';
SELECT *
FROM dbo.TestTable1 T1
WHERE @LookupValue IS NULL
OR EXISTS ( SELECT TOP (1) 1 A FROM dbo.TestTable2 T2 WHERE T1.ID = T2.ID AND T2.TextValue = @LookupValue)
OPTION (RECOMPILE);
As you can see from the query plan below with the recompile table 2 is effectively removed from the execution.
There is however a cost to recompiling, and I'm looking to trace this overhead so I can make sensible decisions as to which of our queries to format in this way. In general I am seeing that recompiling is consistently faster but there are lots of post stating that this means the execution plans can come out as being far less than optimal.
Any guidance on measuring these overheads or any issues I should investigate before implementing this more widely would be gratefully received.
Many thanks.