September 17, 2018 at 12:48 pm
Jason A. Long - Monday, September 17, 2018 11:54 AMIt's only the fastest because it was the only horse in the race...
Lets give it a little competition...Start by adding a POC index...
--POC index...
CREATE NONCLUSTERED INDEX ix_SellerProductsSnapshots_POC
ON dbo.SellerProductsSnapshots (
IdSeller ASC,
Date DESC
)
INCLUDE (
ProductsCount,
AvgPrice
);Note: setting SSMS to "Discard results after execution" to prevent display rendering from impacting results..
SET NOCOUNT ON;
GOGO
-- DBCC FLUSHPROCINDB(16) WITH NO_INFOMSGS;
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
--EXEC master.dbo.sp_DBCC_DropCleanBuffers_FreeProcCache;
PRINT(CONCAT(CHAR(13), CHAR(10), N' wait a moment...', CHAR(13), CHAR(10)));
WAITFOR DELAY '00:00:01';
GO
-- SET STATISTICS XML ON;
GO
DECLARE @_clock_start DATETIME2(7) = SYSDATETIME(), @_test_name NVARCHAR(70) = N' ';
PRINT(CONCAT(N'â•”', REPLICATE(N'â•', 148), N'â•—
â•‘', LEFT(CONCAT(N' Start Time: ', @_clock_start, N' Test Name: ', ISNULL(NULLIF(@_test_name, N' '), N'Test Query 1'),
REPLICATE(N' ', 100)), 148), N'â•‘', CHAR(13), CHAR(10), N'â•š', REPLICATE(N'â•', 148), N'â•')); DECLARE @_data_dump_int INT; SET STATISTICS IO ON;
-- ____________________________________________________________________________________________________________________________________________
-- ⇩⇩⇩⇩⇩⇩ place tsql here ⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩
;WITH CTE AS
(
SELECT DISTINCT
sps.IdSeller
FROM SellerProductsSnapshots sps
WHERE EXISTS(SELECT *
FROM #SellersTable st
WHERE st.Id = sps.IdSeller)
)
SELECT sps.IdSeller,
sps2.ProductsCount,
sps2.AvgPrice
FROM CTE sps
CROSS APPLY(SELECT TOP(1)
sps2.ProductsCount,
sps2.AvgPrice,
sps2.Date
FROM SellerProductsSnapshots sps2
WHERE sps2.IdSeller = sps.IdSeller
ORDER BY sps2.Date DESC) AS sps2;
-- ⇧⇧⇧⇧⇧⇧ place tsql here ⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧
-- ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
DECLARE @_clock_stop DATETIME2(7) = SYSDATETIME(); SET STATISTICS IO OFF; PRINT(CONCAT(N'â•”', REPLICATE(N'â•', 148), N'â•—
â•‘', LEFT(STUFF(CONCAT(N' Finish Time: ', @_clock_stop, N' Duration: ', DATEDIFF(mcs, @_clock_start, @_clock_stop)
/ 1000000.0, N' secs. ', DATEDIFF(mcs, @_clock_start, @_clock_stop) / 1000.0, N' ms.', REPLICATE(N' ', 100)), 76, 3, N''), 148), N'â•‘
â•š', REPLICATE(N'â•', 148), N'â•'));
GO
-- SET STATISTICS XML OFF;
GO
-- DBCC FLUSHPROCINDB(16) WITH NO_INFOMSGS;
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
--EXEC master.dbo.sp_DBCC_DropCleanBuffers_FreeProcCache;
PRINT(CONCAT(CHAR(13), CHAR(10), N' wait a moment...', CHAR(13), CHAR(10)));
WAITFOR DELAY '00:00:01';
GO
-- SET STATISTICS XML ON;
GO
DECLARE @_clock_start DATETIME2(7) = SYSDATETIME(), @_test_name NVARCHAR(70) = N' ';
PRINT(CONCAT(N'â•”', REPLICATE(N'â•', 148), N'â•—
â•‘', LEFT(CONCAT(N' Start Time: ', @_clock_start, N' Test Name: ', ISNULL(NULLIF(@_test_name, N' '), N'Test Query 2'),
REPLICATE(N' ', 100)), 148), N'â•‘', CHAR(13), CHAR(10), N'â•š', REPLICATE(N'â•', 148), N'â•')); DECLARE @_data_dump_int INT; SET STATISTICS IO ON;
-- ____________________________________________________________________________________________________________________________________________
-- ⇩⇩⇩⇩⇩⇩ place tsql here ⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩
WITH
cte_AddRN AS (
SELECT
sps.IdSeller,
sps.ProductsCount,
sps.AvgPrice,
sps.Date,
rn= ROW_NUMBER() OVER (PARTITION BY sps.IdSeller ORDER BY sps.Date DESC)
FROM
dbo.SellerProductsSnapshots sps
)
SELECT
IdSeller = st.Id, arn.ProductsCount, arn.AvgPrice
FROM
#SellersTable st
INNER MERGE JOIN cte_AddRN arn -- (since both tables are order on Id (IdSeller a MERGE join is appropriate...
ON st.Id = arn.IdSeller
WHERE
arn.rn = 1;
-- ⇧⇧⇧⇧⇧⇧ place tsql here ⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧
-- ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
DECLARE @_clock_stop DATETIME2(7) = SYSDATETIME(); SET STATISTICS IO OFF; PRINT(CONCAT(N'â•”', REPLICATE(N'â•', 148), N'â•—
â•‘', LEFT(STUFF(CONCAT(N' Finish Time: ', @_clock_stop, N' Duration: ', DATEDIFF(mcs, @_clock_start, @_clock_stop)
/ 1000000.0, N' secs. ', DATEDIFF(mcs, @_clock_start, @_clock_stop) / 1000.0, N' ms.', REPLICATE(N' ', 100)), 76, 3, N''), 148), N'â•‘
â•š', REPLICATE(N'â•', 148), N'â•'));
GO
-- SET STATISTICS XML OFF;
GO
-- DBCC FLUSHPROCINDB(16) WITH NO_INFOMSGS;
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
--EXEC master.dbo.sp_DBCC_DropCleanBuffers_FreeProcCache;
PRINT(CONCAT(CHAR(13), CHAR(10), N' wait a moment...', CHAR(13), CHAR(10)));
WAITFOR DELAY '00:00:01';
GO
-- SET STATISTICS XML ON;
GO
DECLARE @_clock_start DATETIME2(7) = SYSDATETIME(), @_test_name NVARCHAR(70) = N' ';
PRINT(CONCAT(N'â•”', REPLICATE(N'â•', 148), N'â•—
â•‘', LEFT(CONCAT(N' Start Time: ', @_clock_start, N' Test Name: ', ISNULL(NULLIF(@_test_name, N' '), N'Test Query 3'),
REPLICATE(N' ', 100)), 148), N'â•‘', CHAR(13), CHAR(10), N'â•š', REPLICATE(N'â•', 148), N'â•')); DECLARE @_data_dump_int INT; SET STATISTICS IO ON;
-- ____________________________________________________________________________________________________________________________________________
-- ⇩⇩⇩⇩⇩⇩ place tsql here ⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩⇩
SELECT
IdSeller = st.Id,
ProductsCount = CONVERT(INT, SUBSTRING(spsx.max_bin_val, 9, 4)),
AvgPrice = CONVERT(MONEY, SUBSTRING(spsx.max_bin_val, 13, 8))
FROM
#SellersTable st
CROSS APPLY (
SELECT
MAX(CONVERT(BINARY(8), sps.Date) + CONVERT(BINARY(4), sps.ProductsCount) + CONVERT(BINARY(8), sps.AvgPrice))
FROM
dbo.SellerProductsSnapshots sps
WHERE
st.Id = sps.IdSeller
) spsx (max_bin_val);
-- ⇧⇧⇧⇧⇧⇧ place tsql here ⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧⇧
-- ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
DECLARE @_clock_stop DATETIME2(7) = SYSDATETIME(); SET STATISTICS IO OFF; PRINT(CONCAT(N'â•”', REPLICATE(N'â•', 148), N'â•—
â•‘', LEFT(STUFF(CONCAT(N' Finish Time: ', @_clock_stop, N' Duration: ', DATEDIFF(mcs, @_clock_start, @_clock_stop)
/ 1000000.0, N' secs. ', DATEDIFF(mcs, @_clock_start, @_clock_stop) / 1000.0, N' ms.', REPLICATE(N' ', 100)), 76, 3, N''), 148), N'â•‘
â•š', REPLICATE(N'â•', 148), N'â•'));
GO
-- SET STATISTICS XML OFF;
GOThe results
wait a moment...
â•”â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•—
â•‘ Start Time: 2018-09-17 13:40:04.7958330 Test Name: Test Query 1 â•‘
â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
Table 'SellerProductsSnapshots'. Scan count 1000001, logical reads 3196940, physical reads 1, read-ahead reads 4719, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#SellersTable_______________________________________________________________________________________________________0000000049C6'. Scan count 1, logical reads 2733, physical reads 0, read-ahead reads 16, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
â•”â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•—
â•‘ Finish Time: 2018-09-17 13:40:08.8240652 Duration: 4.028232 secs. 4028.232000 ms. â•‘
â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•wait a moment...
â•”â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•—
â•‘ Start Time: 2018-09-17 13:40:10.0431337 Test Name: Test Query 2 â•‘
â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'SellerProductsSnapshots'. Scan count 1, logical reads 4718, physical reads 1, read-ahead reads 4711, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#SellersTable_______________________________________________________________________________________________________0000000049C6'. Scan count 1, logical reads 2733, physical reads 0, read-ahead reads 16, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
â•”â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•—
â•‘ Finish Time: 2018-09-17 13:40:12.2462594 Duration: 2.203126 secs. 2203.126000 ms. â•‘
â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•wait a moment...
â•”â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•—
â•‘ Start Time: 2018-09-17 13:40:13.5003326 Test Name: Test Query 3 â•‘
â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
Table '#SellersTable_______________________________________________________________________________________________________0000000049C6'. Scan count 1, logical reads 2733, physical reads 0, read-ahead reads 16, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'SellerProductsSnapshots'. Scan count 1, logical reads 4718, physical reads 1, read-ahead reads 4711, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
â•”â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•—
â•‘ Finish Time: 2018-09-17 13:40:15.2564298 Duration: 1.756097 secs. 1756.097000 ms. â•‘
â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
Your queries assume that Id is unique on #SellersTable. If it isn't (it states nowhere that it is) your queries don't work.
For example if you set up the test data like this:set statistics io,time off
IF OBJECT_ID('tempdb..#SellersTable') IS NOT NULL
DROP TABLE #SellersTable
GO
DECLARE @RowsToInsert as int = 1000000
;WITH A(A) AS
(SELECT 'Anything' FROM (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) A(A)),
B(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1 A))-1 FROM A A, A B, A C, A D, A E, A F, A G, A H)
SELECT TOP(@RowsToInsert) N Id
INTO #SellersTable
FROM B
INSERT INTO #SellersTable
SELECT TOP(@RowsToInsert/2) * FROM #SellersTable
GO
IF OBJECT_ID('dbo.SellerProductsSnapshots') IS NOT NULL
DROP TABLE SellerProductsSnapshots
CREATE TABLE SellerProductsSnapshots
(
IdSeller int NOT NULL,
ProductsCount int NOT NULL,
AvgPrice money NOT NULL,
Date datetime NOT NULL
)
GO
INSERT INTO SellerProductsSnapshots
(
IdSeller,
ProductsCount,
AvgPrice,
Date
)
SELECT Id,
ABS(CHECKSUM(NewId())) % 50 + 5,
ABS(CHECKSUM(NewId())) % 100,
DATEADD(dd,ABS(CHECKSUM(NewId())) % 100,'20180101')
FROM #SellersTable
GO 6
CREATE CLUSTERED INDEX IX_SellerProductsSnapshots_1 ON SellerProductsSnapshots(IdSeller,[Date],ProductsCount,AvgPrice);
CREATE CLUSTERED INDEX IX_#SellersTable_1 ON #SellersTable(Id);
And then run this code:if object_id('tempdb..#1') is not null
DROP TABLE #1
if object_id('tempdb..#2') is not null
DROP TABLE #2
if object_id('tempdb..#3') is not null
DROP TABLE #3
GO
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
set statistics io,time on
GO
PRINT 'Query 1 *************************************************************************************************************'
;WITH CTE AS
(
SELECT DISTINCT
sps.IdSeller
FROM SellerProductsSnapshots sps
WHERE EXISTS(SELECT *
FROM #SellersTable st
WHERE st.Id = sps.IdSeller)
)
SELECT sps.IdSeller,
sps2.ProductsCount,
sps2.AvgPrice
INTO #1
FROM CTE sps
CROSS APPLY(SELECT TOP(1)
sps2.ProductsCount,
sps2.AvgPrice,
sps2.Date
FROM SellerProductsSnapshots sps2
WHERE sps2.IdSeller = sps.IdSeller
ORDER BY sps2.Date DESC) AS sps2;
GO
PRINT 'Query 1 End *************************************************************************************************************'
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
GO
PRINT 'Query 2 *************************************************************************************************************'
GO
;WITH
cte_AddRN AS (
SELECT
sps.IdSeller,
sps.ProductsCount,
sps.AvgPrice,
sps.Date,
rn= ROW_NUMBER() OVER (PARTITION BY sps.IdSeller ORDER BY sps.Date DESC)
FROM
dbo.SellerProductsSnapshots sps
)
SELECT
IdSeller = st.Id, arn.ProductsCount, arn.AvgPrice
INTO #2
FROM
#SellersTable st
INNER MERGE JOIN cte_AddRN arn -- (since both tables are order on Id (IdSeller a MERGE join is appropriate...
ON st.Id = arn.IdSeller
WHERE
arn.rn = 1;
PRINT 'Query 2 End *************************************************************************************************************'
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
PRINT(CONCAT(CHAR(13), CHAR(10), N' wait a moment...', CHAR(13), CHAR(10)));
GO
PRINT 'Query 3 *************************************************************************************************************'
SELECT
IdSeller = st.Id,
ProductsCount = CONVERT(INT, SUBSTRING(spsx.max_bin_val, 9, 4)),
AvgPrice = CONVERT(MONEY, SUBSTRING(spsx.max_bin_val, 13, 8))
INTO #3
FROM
#SellersTable st
CROSS APPLY (
SELECT
MAX(CONVERT(BINARY(8), sps.Date) + CONVERT(BINARY(4), sps.ProductsCount) + CONVERT(BINARY(8), sps.AvgPrice))
FROM
dbo.SellerProductsSnapshots sps
WHERE
st.Id = sps.IdSeller
) spsx (max_bin_val);
GO
PRINT 'Query 3 End *************************************************************************************************************'
set statistics io,time off
select count(*) from #1
select count(*) from #2
select count(*) from #3
You get this:
Also the times I get are here:
Query 1 - CPU time = 7984 ms, elapsed time = 1513 ms.
Query 2 - CPU time = 13358 ms, elapsed time = 3597 ms.
Query 3 - CPU time = 7048 ms, elapsed time = 1079 ms.
If I'd assumed that Id was unique on #SellersTable I would have written my query like this:SELECT st.Id IdSeller,
sps2.ProductsCount,
sps2.AvgPrice
FROM #SellersTable st
CROSS APPLY(SELECT TOP(1)
sps2.ProductsCount,
sps2.AvgPrice,
sps2.Date
FROM SellerProductsSnapshots sps2
WHERE sps2.IdSeller = st.Id
ORDER BY sps2.Date DESC) AS sps2;
Which I think beats all the other queries.
September 17, 2018 at 1:51 pm
Why would you not assume that?
Given that it's a temp table there's a pretty high likelihood that it's being populated with a distinct set of values, specifically for this query.
Doing unnecessary DISTINCT operations because "just in case", isn't kind to performance.
September 17, 2018 at 2:28 pm
Jason A. Long - Monday, September 17, 2018 1:51 PMWhy would you not assume that?
Given that it's a temp table there's a pretty high likelihood that it's being populated with a distinct set of values, specifically for this query.
Doing unnecessary DISTINCT operations because "just in case", isn't kind to performance.
Well maybe you're right to assume that and I'm not. But the result is we ended up with functionally different queries.
September 17, 2018 at 2:28 pm
Jason A. Long - Monday, September 17, 2018 1:51 PMWhy would you not assume that?
Given that it's a temp table there's a pretty high likelihood that it's being populated with a distinct set of values, specifically for this query.
Doing unnecessary DISTINCT operations because "just in case", isn't kind to performance.
Well maybe you're right to assume that and I'm not. But the result is we ended up with functionally different queries.
September 17, 2018 at 2:55 pm
Jonathan AC Roberts - Monday, September 17, 2018 2:28 PMJason A. Long - Monday, September 17, 2018 1:51 PMWhy would you not assume that?
Given that it's a temp table there's a pretty high likelihood that it's being populated with a distinct set of values, specifically for this query.
Doing unnecessary DISTINCT operations because "just in case", isn't kind to performance.Well maybe you're right to assume that and I'm not. But the result is we ended up with functionally different queries.
How so? All 3 queries produce exactly 1M rows and a random spot check is showing identical ProductCount & AvgPrice values...
September 17, 2018 at 5:24 pm
Jason A. Long - Monday, September 17, 2018 2:55 PMJonathan AC Roberts - Monday, September 17, 2018 2:28 PMJason A. Long - Monday, September 17, 2018 1:51 PMWhy would you not assume that?
Given that it's a temp table there's a pretty high likelihood that it's being populated with a distinct set of values, specifically for this query.
Doing unnecessary DISTINCT operations because "just in case", isn't kind to performance.Well maybe you're right to assume that and I'm not. But the result is we ended up with functionally different queries.
How so? All 3 queries produce exactly 1M rows and a random spot check is showing identical ProductCount & AvgPrice values...
Did you try the data setup in this reply? The queries return different results. Your queries produce 1.5 million rows. The queries are functionally different.
September 17, 2018 at 6:53 pm
Jonathan AC Roberts - Monday, September 17, 2018 5:24 PMJason A. Long - Monday, September 17, 2018 2:55 PMJonathan AC Roberts - Monday, September 17, 2018 2:28 PMJason A. Long - Monday, September 17, 2018 1:51 PMWhy would you not assume that?
Given that it's a temp table there's a pretty high likelihood that it's being populated with a distinct set of values, specifically for this query.
Doing unnecessary DISTINCT operations because "just in case", isn't kind to performance.Well maybe you're right to assume that and I'm not. But the result is we ended up with functionally different queries.
How so? All 3 queries produce exactly 1M rows and a random spot check is showing identical ProductCount & AvgPrice values...
Did you try the data setup in this reply? The queries return different results. Your queries produce 1.5 million rows. The queries are functionally different.
Not the way I wrote them, they didn't. The The 3 queries I posted all produced 1M rows apeace. I went back and reverified after you posted just to make sure. I'm not sure what you did to make it output 1.5M rows,
September 17, 2018 at 7:11 pm
Jason A. Long - Monday, September 17, 2018 6:53 PMNot the way I wrote them, they didn't. The The 3 queries I posted all produced 1M rows apeace. I went back and reverified after you posted just to make sure. I'm not sure what you did to make it output 1.5M rows,
Actually, There is one thing that I can think of that may account for the descrepancy... I used you table setup code, including the values in the temp table. I made a point to verify uniqueness by comparing the count(*) value to the count(DISTINCT SellerId) value and came up with 1M for each... If you added half a mil of duplicates into the temp table on your end, that would account for the the difference... Being that you did include a DISTINCT step and I didn't.
I don't know that to be the case but it's the only reasonable explination that comes to mind at the moment.
Viewing 8 posts - 16 through 22 (of 22 total)
You must be logged in to reply to this topic. Login to reply