I am lost why execution plan is different if I run query with option recompile to compare to same query (with clean proc cache) without option recompile. The result is one row. The script is:
Create two tables:
CREATE TABLE H (id INT PRIMARY KEY CLUSTERED IDENTITY(1,1), header CHAR(100))
CREATE TABLE D (id INT PRIMARY KEY CLUSTERED IDENTITY(1,1), idH INT, detail CHAR(100))
CREATE INDEX IX_idH ON dbo.D(idH)
Fulfill:
DECLARE @i int = 1
WHILE @i <= 10
BEGIN
INSERT INTO H (header) VALUES ('nonononono')
SET @i = @i + 1
PRINT @i
END
SELECT * FROM H
GO
DECLARE @i int = 1
DECLARE @ii int = 1
WHILE @i <= 7
BEGIN
WHILE @ii <= POWER (10,(@i - 1))
BEGIN
INSERT INTO D (idH, detail) VALUES (@i, 'nonononono')
SET @ii = @ii + 1
END
SET @i = @i + 1
SET @ii = 1
END
The statement:
DBCC FREESESSIONCACHE
DECLARE @hid INT = 1
SELECT *
FROM H h
JOIN D d ON d.idH = h.id
WHERE h.id = @hid
OPTION (RECOMPILE)
With OPTION (RECOMPILE) it uses the key lookup for the D table, without it uses scan for D table. I do not understand why. MS SQL version 13.0.4411.0. And simple (7 rows) and actual statistics.