Using SQL Server 2016 and later
I am currently evaluating two methods of displaying search results. Display all "products" that match a "criteria".
I was looking into the merits of storing the list of IDs that match the criteria in a temp table and then joining back to my main products vs a dynamically created session view that has the IDs coded in as values.
Sample of scripts below. I've omitted the main product table itself as its just a large flat table but does hold company proprietary details. The code itself isn't an issue rather the stats it generates.
SET STATISTICS IO, TIME OFF;
DROP TABLE IF EXISTS dba.Temp;
DROP VIEW IF EXISTS dba.Test1;
DROP VIEW IF EXISTS dba.Test2;
CREATE TABLE dba.Temp (ProductID INT);
INSERT INTO dba.Temp (ProductID)
SELECT TOP 1000
ProductID
FROM dbo.Products
ORDER BY NEWID();
GO
CREATE VIEW dba.Test1
AS
SELECT P.*
FROM Products P
JOIN dba.Temp T ON T.ProductID = P.ProductID;
GO
DECLARE @strSQL AS NVARCHAR(MAX);
SET @strSQL = N'';
SELECT @strSQL = @strSQL + N',(' + CAST(ProductID AS NVARCHAR(MAX)) + N')'
FROM dba.Temp;
SET @strSQL = STUFF(@strSQL, 1, 1, ('CREATE VIEW dba.Test2 AS SELECT P.* FROM Products P JOIN (VALUES ')) + N') T (ProductID) ON T.ProductID = P.ProductID';
EXEC sp_executesql @stmt = @strSQL;
GO
SET STATISTICS IO, TIME ON;
PRINT '------------------------------ Test 1';
SELECT * FROM dba.Test1;
PRINT '------------------------------ Test 2';
SELECT * FROM dba.Test2;
PRINT '------------------------------ End';
SET STATISTICS IO, TIME OFF;
I've found there was very little difference between the two options on my data sets, but I was getting some very strange results depending on how I tested.
If I read only from test 1 I have received statistics similar to the below with minor fluctuations on elapsed time - I'm not the only user on the server.
SQL Server parse and compile time:
CPU time = 8 ms, elapsed time = 8 ms.
------------------------------ Test 1
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
(1000 rows affected)
Table 'Products'. Scan count 0, logical reads 3071, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Temp'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 47 ms, elapsed time = 56 ms.
Running Test 2, I received very similar results only with lower IO (expected as the temp table was not being read from)
SQL Server parse and compile time:
CPU time = 46 ms, elapsed time = 46 ms.
------------------------------ Test 2
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
(1000 rows affected)
Table 'Products'. Scan count 0, logical reads 3071, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 47 ms, elapsed time = 57 ms.
However running the two test together I see consistantly slower results on which ever query is run second.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
------------------------------ Test 1
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
(1000 rows affected)
Table 'Products'. Scan count 0, logical reads 3063, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Temp'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 47 ms, elapsed time = 56 ms.
------------------------------ Test 2
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
(1000 rows affected)
Table 'Products'. Scan count 0, logical reads 3063, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 62 ms, elapsed time = 200 ms.
------------------------------ End
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Is there any logical reason for the skewed results for the second query? Is it that the first query is creating load that affects the second query? I'm wondering if I'm missing something or have a fundamental misunderstanding. This is how I would usually tune my processes, emphasis on IO, keep an eye on time. If I need to adjust my tuning methodology then any advice would be gratefully received.