1+ -- Param Sniffing with Hash Spill
2+
3+ -- Setup
4+ -- USE AdventureWorks2014
5+ USE AdventureWorks2016CTP3
6+ GO
7+ DROP TABLE CustomersState
8+ GO
9+ CREATE TABLE CustomersState (CustomerID int PRIMARY KEY , [Address] CHAR (200 ), [State] CHAR (2 ))
10+ GO
11+ INSERT INTO CustomersState (CustomerID, [Address])
12+ SELECT CustomerID, ' Address' FROM Sales .Customer
13+ GO
14+ UPDATE CustomersState SET [State] = ' NY' WHERE CustomerID % 100 <> 1
15+ UPDATE CustomersState SET [State] = ' WA' WHERE CustomerID % 100 = 1
16+ GO
17+
18+ UPDATE STATISTICS CustomersState WITH FULLSCAN
19+ GO
20+
21+ CREATE PROCEDURE CustomersByState @State CHAR (2 ) AS
22+ BEGIN
23+ DECLARE @CustomerID int
24+ SELECT @CustomerID = e .CustomerID FROM Sales .Customer e
25+ INNER JOIN CustomersState es ON e .CustomerID = es .CustomerID
26+ WHERE es.[State] = @State
27+ OPTION (MAXDOP 1 )
28+ END
29+ GO
30+
31+ -- Get Actual Execution Plan
32+
33+ -- Execute the stored procedure first with parameter value ‘WA’ – which will select 1% of data.
34+ DBCC FREEPROCCACHE
35+ GO
36+ EXEC CustomersByState ' WA'
37+ GO
38+
39+ EXEC CustomersByState ' NY'
40+ GO
41+
42+ /*
43+ Observe the type of Spill = Recursion
44+ Occurs when the build input does not fit into available memory,
45+ resulting in the split of input into multiple partitions that are processed separately.
46+
47+ If any of these partitions still do not fit into available memory,
48+ it is split into sub-partitions, which are also processed separately.
49+ This splitting process continues until each partition fits into available memory
50+ or until the maximum recursion level is reached.
51+ In this case it stopped at level 1.
52+ */
0 commit comments