**When running the query outside of the function to look at the query plans, some differences are found** *Sample data, tests with the actual functions + possible rewrite can be found below* DECLARE @objectid uniqueidentifier select top(1) @objectid = GUIDS from #TEMP; -- function 1 ,omitted the return 0 IF (SELECT TOP(1) 1 FROM StateChanges WHERE LinkedObjectId=@objectId AND (ChangeType = 1 OR ChangeType = 2 ) ) IS NOT NULL BEGIN SELECT 1; END -- Function 2 changed the returns DECLARE @result BIT SET @result = 0 SELECT TOP(1) @result=1 FROM StateChanges WHERE LinkedObjectId=@objectId AND (ChangeType = 1 OR ChangeType = 2 ) SELECT @result; **Function V1:** [![enter image description here][1]][1] *Nested loop left outer join is present in the plan, as to facilitate the IF ... IS NOT NULL check* **Function V2** [![enter image description here][2]][2] *No nested loop operator, a more simple, straightforward plan* As seen, a nested loop left join was added because of the IF check, if we execute the query without the IF statement: DECLARE @objectid uniqueidentifier select top(1) @objectid = GUIDS from #TEMP; SELECT TOP(1) 1 FROM StateChanges WHERE LinkedObjectId=@objectId AND (ChangeType = 1 OR ChangeType = 2 ); [![enter image description here][3]][3] *No more Nested loops and the same plan as V2 is seen* Which should explain the increased worker time, since adding the nested loop operators to check for the `IS NULL` will increase CPU usage. To answer your question, yes the IF statement should increase your CPU usage, as a result of the additional operators. ---------- **Testing with the previous defined tables, indexes, functions and adding some data** CREATE TABLE #TEMP(GUIDS uniqueidentifier) DECLARE @GUID uniqueidentifier declare @i int =1 WHILE @i <= 1000 BEGIN SET @GUID = NEWID() INSERT INTO #temp(GUIDS) VALUES(@GUID) SET @I += 1 END SET NOCOUNT OFF; INSERT INTO [dbo].[StateChanges]([RecordId],[LinkedObjectId], [ChangeType],[ChangeTime], SomeColumnsHere ) SELECT GUIDS, GUIDS , 5, getdate(), 'Blabla' from #TEMP **Testing the functions** SELECT [dbo].[ObjectHasInterestingChanges_v1](GUIDS) FROM #temp; > SQL Server Execution Times: CPU time = 125 ms, elapsed time = 125 > ms. SELECT [dbo].ufn_ObjectHasInterestingChanges_v2(GUIDS) FROM #temp ; > SQL Server Execution Times: CPU time = 125 ms, elapsed time = 132 > ms. *they appear to get the same CPU time with a low dataset and no matches (nothing matches because Changetype is not 1 or 2 in my data).* **On another note, you could change the function to outer apply** SELECT ISNULL(a.bla,0) FROM #TEMP OUTER APPLY (SELECT TOP(1) 1 as bla FROM StateChanges WHERE LinkedObjectId=GUIDS AND (ChangeType = 1 OR ChangeType = 2 ) ) as a > SQL Server Execution Times: CPU time = 0 ms, elapsed time = 5 ms. **Test 2, adding some mathing data** DECLARE @GUID uniqueidentifier declare @i int =1 WHILE @i <= 1000 BEGIN SET @GUID = NEWID() INSERT INTO #temp(GUIDS) VALUES(@GUID) SET @I += 1 END SET NOCOUNT OFF; INSERT INTO [dbo].[StateChanges]([RecordId],[LinkedObjectId], [ChangeType],[ChangeTime], SomeColumnsHere ) SELECT GUIDS, GUIDS ,2, getdate(), 'Blabla' from #TEMP; **Testing the functions and the rewrite again** SELECT ISNULL(a.bla,0) FROM #TEMP OUTER APPLY (SELECT TOP(1) 1 as bla FROM StateChanges WHERE LinkedObjectId=GUIDS AND (ChangeType = 1 OR ChangeType = 2 ) ) as a; > SQL Server Execution Times: CPU time = 31 ms, elapsed time = 21 > ms. SELECT [dbo].[ObjectHasInterestingChanges_v1](GUIDS) FROM #temp; > SQL Server Execution Times: CPU time = 375 ms, elapsed time = 378 > ms. SELECT [dbo].ufn_ObjectHasInterestingChanges_v2(GUIDS) FROM #temp ; > SQL Server Execution Times: CPU time = 344 ms, elapsed time = 352 > ms. *A difference between function 1 and 2 appears as the dataset + matches increases!* ---------- [1]: https://i.sstatic.net/ABe8k.png [2]: https://i.sstatic.net/oIKj8.png [3]: https://i.sstatic.net/sXKHk.png