আমি সারোগেট চাবিগুলির একটি অনুরাগী। আমার ফলাফলগুলি নিশ্চিতকরণ পক্ষপাতদুষ্ট হওয়ার ঝুঁকি রয়েছে।
অনেক প্রশ্ন আমি এখানে এবং http://stackoverflow.com এ উভয়ই দেখেছি IDENTITY()
মানগুলির উপর ভিত্তি করে সার্গেট কীগুলির পরিবর্তে প্রাকৃতিক কীগুলি ব্যবহার করে ।
কম্পিউটার সিস্টেমে আমার ব্যাকগ্রাউন্ড আমাকে বলছে যে কোনও পূর্ণসংখ্যার তুলনায় তুলনামূলক অপারেশন করা স্ট্রিংগুলির সাথে তুলনা করার চেয়ে দ্রুত হবে be
এই মন্তব্যটি আমার বিশ্বাসকে প্রশ্নবিদ্ধ করেছিল, তাই আমি ভেবেছিলাম যে আমি আমার থিসিসটি তদন্তের জন্য একটি সিস্টেম তৈরি করব যা এসকিউএল সার্ভারে কী হিসাবে ব্যবহারের জন্য স্ট্রিংয়ের চেয়েও পূর্ণতর হয়।
যেহেতু ছোট ডেটাসেটগুলিতে খুব সামান্য বোধগম্য পার্থক্য হওয়ার সম্ভাবনা রয়েছে তাই আমি তত্ক্ষণাত্ দুটি টেবিল সেটআপের কথা ভেবেছিলাম যেখানে প্রাথমিক টেবিলটিতে এক হাজার সারি রয়েছে এবং দ্বিতীয় সারণীতে মোট সারণীতে ১০,০০,০০০ সারি রয়েছে গৌণ সারণী আমার পরীক্ষার মূল ভিত্তি হ'ল এই জাতীয় দুটি টেবিলের সেট তৈরি করা, একটি প্রাকৃতিক কী ব্যবহার করা এবং একটিতে পূর্ণসংখ্যা কী ব্যবহার করা এবং টাইমিং টেস্টগুলি সাধারণ জিজ্ঞাসায় চালানো যেমন:
SELECT *
FROM Table1
INNER JOIN Table2 ON Table1.Key = Table2.Key;
পরীক্ষার বিছানা হিসাবে আমি তৈরি কোডটি নিম্নলিখিত:
USE Master;
IF (SELECT COUNT(database_id) FROM sys.databases d WHERE d.name = 'NaturalKeyTest') = 1
BEGIN
ALTER DATABASE NaturalKeyTest SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE NaturalKeyTest;
END
GO
CREATE DATABASE NaturalKeyTest
ON (NAME = 'NaturalKeyTest', FILENAME =
'C:\SQLServer\Data\NaturalKeyTest.mdf', SIZE=8GB, FILEGROWTH=1GB)
LOG ON (NAME='NaturalKeyTestLog', FILENAME =
'C:\SQLServer\Logs\NaturalKeyTest.mdf', SIZE=256MB, FILEGROWTH=128MB);
GO
ALTER DATABASE NaturalKeyTest SET RECOVERY SIMPLE;
GO
USE NaturalKeyTest;
GO
CREATE VIEW GetRand
AS
SELECT RAND() AS RandomNumber;
GO
CREATE FUNCTION RandomString
(
@StringLength INT
)
RETURNS NVARCHAR(max)
AS
BEGIN
DECLARE @cnt INT = 0
DECLARE @str NVARCHAR(MAX) = '';
DECLARE @RandomNum FLOAT = 0;
WHILE @cnt < @StringLength
BEGIN
SELECT @RandomNum = RandomNumber
FROM GetRand;
SET @str = @str + CAST(CHAR((@RandomNum * 64.) + 32) AS NVARCHAR(MAX));
SET @cnt = @cnt + 1;
END
RETURN @str;
END;
GO
CREATE TABLE NaturalTable1
(
NaturalTable1Key NVARCHAR(255) NOT NULL
CONSTRAINT PK_NaturalTable1 PRIMARY KEY CLUSTERED
, Table1TestData NVARCHAR(255) NOT NULL
);
CREATE TABLE NaturalTable2
(
NaturalTable2Key NVARCHAR(255) NOT NULL
CONSTRAINT PK_NaturalTable2 PRIMARY KEY CLUSTERED
, NaturalTable1Key NVARCHAR(255) NOT NULL
CONSTRAINT FK_NaturalTable2_NaturalTable1Key
FOREIGN KEY REFERENCES dbo.NaturalTable1 (NaturalTable1Key)
ON DELETE CASCADE ON UPDATE CASCADE
, Table2TestData NVARCHAR(255) NOT NULL
);
GO
/* insert 1,000,000 rows into NaturalTable1 */
INSERT INTO NaturalTable1 (NaturalTable1Key, Table1TestData)
VALUES (dbo.RandomString(25), dbo.RandomString(100));
GO 1000000
/* insert 10,000,000 rows into NaturalTable2 */
INSERT INTO NaturalTable2 (NaturalTable2Key, NaturalTable1Key, Table2TestData)
SELECT dbo.RandomString(25), T1.NaturalTable1Key, dbo.RandomString(100)
FROM NaturalTable1 T1
GO 10
CREATE TABLE IDTable1
(
IDTable1Key INT NOT NULL CONSTRAINT PK_IDTable1
PRIMARY KEY CLUSTERED IDENTITY(1,1)
, Table1TestData NVARCHAR(255) NOT NULL
CONSTRAINT DF_IDTable1_TestData DEFAULT dbo.RandomString(100)
);
CREATE TABLE IDTable2
(
IDTable2Key INT NOT NULL CONSTRAINT PK_IDTable2
PRIMARY KEY CLUSTERED IDENTITY(1,1)
, IDTable1Key INT NOT NULL
CONSTRAINT FK_IDTable2_IDTable1Key FOREIGN KEY
REFERENCES dbo.IDTable1 (IDTable1Key)
ON DELETE CASCADE ON UPDATE CASCADE
, Table2TestData NVARCHAR(255) NOT NULL
CONSTRAINT DF_IDTable2_TestData DEFAULT dbo.RandomString(100)
);
GO
INSERT INTO IDTable1 DEFAULT VALUES;
GO 1000000
INSERT INTO IDTable2 (IDTable1Key)
SELECT T1.IDTable1Key
FROM IDTable1 T1
GO 10
উপরের কোডটি একটি ডাটাবেস এবং 4 টি সারণী তৈরি করে এবং পরীক্ষার জন্য প্রস্তুত টেবিলগুলি ডেটা দিয়ে পূর্ণ করে। আমি যে পরীক্ষার কোডটি চালিয়েছি তা হ'ল:
USE NaturalKeyTest;
GO
DECLARE @loops INT = 0;
DECLARE @MaxLoops INT = 10;
DECLARE @Results TABLE (
FinishedAt DATETIME DEFAULT (GETDATE())
, KeyType NVARCHAR(255)
, ElapsedTime FLOAT
);
WHILE @loops < @MaxLoops
BEGIN
DBCC FREEPROCCACHE;
DBCC FREESESSIONCACHE;
DBCC FREESYSTEMCACHE ('ALL');
DBCC DROPCLEANBUFFERS;
WAITFOR DELAY '00:00:05';
DECLARE @start DATETIME = GETDATE();
DECLARE @end DATETIME;
DECLARE @count INT;
SELECT @count = COUNT(*)
FROM dbo.NaturalTable1 T1
INNER JOIN dbo.NaturalTable2 T2 ON T1.NaturalTable1Key = T2.NaturalTable1Key;
SET @end = GETDATE();
INSERT INTO @Results (KeyType, ElapsedTime)
SELECT 'Natural PK' AS KeyType, CAST((@end - @start) AS FLOAT) AS ElapsedTime;
DBCC FREEPROCCACHE;
DBCC FREESESSIONCACHE;
DBCC FREESYSTEMCACHE ('ALL');
DBCC DROPCLEANBUFFERS;
WAITFOR DELAY '00:00:05';
SET @start = GETDATE();
SELECT @count = COUNT(*)
FROM dbo.IDTable1 T1
INNER JOIN dbo.IDTable2 T2 ON T1.IDTable1Key = T2.IDTable1Key;
SET @end = GETDATE();
INSERT INTO @Results (KeyType, ElapsedTime)
SELECT 'IDENTITY() PK' AS KeyType, CAST((@end - @start) AS FLOAT) AS ElapsedTime;
SET @loops = @loops + 1;
END
SELECT KeyType, FORMAT(CAST(AVG(ElapsedTime) AS DATETIME), 'HH:mm:ss.fff') AS AvgTime
FROM @Results
GROUP BY KeyType;
এগুলি ফলাফল:
আমি কি এখানে কিছু ভুল করছি, বা INT কীগুলি 25 টি অক্ষরের প্রাকৃতিক কীগুলির চেয়ে 3 গুণ বেশি দ্রুত?
দ্রষ্টব্য, আমি এখানে একটি ফলো-আপ প্রশ্ন লিখেছি ।