OK,
Turns out, Scott does not want to discredit his religious beliefs by publishing results of scientific tests.
So I decided to wrap the discussion with doing my own test using Active-Inactive tables.
I've done it in the most efficient way (to my best understanding).
I appreciate that somebody can offer a better way, so any corrections are welcome.
Here is my setup:
CREATE TABLE [dbo].[UsedRedemptionCodes_Active](
[RedemptionCode] [char](36) NOT NULL
CONSTRAINT [PK_UsedRedemptionCodes_Active] PRIMARY KEY CLUSTERED ([RedemptionCode])
)
GO
CREATE TABLE [dbo].[UsedRedemptionCodes_Inactive](
[RedemptionCode] [char](36) NOT NULL,
CONSTRAINT [PK_UsedRedemptionCodes_Inactive] PRIMARY KEY CLUSTERED ([RedemptionCode])
)
GO
INSERT INTO dbo.UsedRedemptionCodes_Active
([RedemptionCode])
SELECT RedemptionCode
FROM dbo.UsedRedemptionCodesTest
WHERE IsActive = 1
ORDER BY RedemptionCode
INSERT INTO dbo.UsedRedemptionCodes_Inactive
([RedemptionCode])
SELECT RedemptionCode
FROM dbo.UsedRedemptionCodesTest
WHERE IsActive = 0
ORDER BY RedemptionCode
I used the records from the same table which I populated in the previous test. So, it's exactly the same recordset.
Now, let's generate new codes:
DECLARE @RedemptionSeed INT
DECLARE @RedemptionCode CHAR(36)
SET STATISTICS IO ON
WHILE((@RedemptionCode IS NULL)
OR EXISTS(SELECT RedemptionCode FROM dbo.UsedRedemptionCodes_Active WHERE RedemptionCode = @RedemptionCode)
OR EXISTS(SELECT RedemptionCode FROM dbo.UsedRedemptionCodes_Inactive WHERE RedemptionCode = @RedemptionCode)
)
BEGIN
SET @RedemptionSeed = (SELECT ABS(CHECKSUM(NEWID())))
SET @RedemptionCode = NEWID() -- dbo.GenerateRandomBase32(@RedemptionSeed)
END
INSERT INTO dbo.UsedRedemptionCodes_Active (RedemptionCode)
VALUES (@RedemptionCode)
SET STATISTICS IO OFF
GO 10
Output statistics:
Beginning execution loop
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 'UsedRedemptionCodes_Inactive'. Scan count 0, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'UsedRedemptionCodes_Active'. Scan count 0, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'UsedRedemptionCodes_Active'. Scan count 0, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
... repeated 8 times ...
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 'UsedRedemptionCodes_Inactive'. Scan count 0, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'UsedRedemptionCodes_Active'. Scan count 0, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'UsedRedemptionCodes_Active'. Scan count 0, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Batch execution completed 10 times.
Aggregated Numbers are pretty much the same as in the first test.
Now - giving away the random codes:
SET STATISTICS PROFILE ON
SET STATISTICS IO ON
SELECT TOP 100 RedemptionCode
INTO #Out
FROM dbo.UsedRedemptionCodes_Active
ORDER BY NEWID() -- we must make sure that the codes are given away in the random order
-- as we cannot allow codes presented in a sequence which would be easy to guess
SELECT * FROM #Out
INSERT INTO UsedRedemptionCodes_Inactive (RedemptionCode)
SELECT RedemptionCode FROM #Out
DELETE FROM dbo.UsedRedemptionCodes_Active
WHERE EXISTS (SELECT * FROM #Out
WHERE #Out.RedemptionCode = dbo.UsedRedemptionCodes_Active.RedemptionCode)
SET STATISTICS IO OFF
SET STATISTICS PROFILE OFF
DROP TABLE #Out
And the stats:
Table 'UsedRedemptionCodes_Active'. Scan count 1, logical reads 605, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#Out________________________________________________________________________________________________________________0000000000CA'. 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.
Table 'UsedRedemptionCodes_Inactive'. Scan count 0, logical reads 1140, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#Out________________________________________________________________________________________________________________0000000000CA'. 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.
Table 'UsedRedemptionCodes_Active'. Scan count 0, logical reads 615, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#Out________________________________________________________________________________________________________________0000000000CA'. 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.
Aggregated numbers are on the same level as in the test with a single table, only actually "a little" worse.
Conclusion:
Partitioning of a table not only does not improve performance, it actually makes it worse.
_____________
Code for TallyGenerator