আমার পরীক্ষার ক্ষেত্রে সিক্যুয়াল জিআইইডি কীগুলি অনুক্রমিক আইএনটি কীগুলির চেয়ে দ্রুত সঞ্চালন করে কেন?


39

এই প্রশ্নটি অনুক্রমিক এবং অ-অনুক্রমিক জিইউডিগুলির সাথে তুলনা করার পরে , আমি ইনসার্টের পারফরম্যান্স 1 এর সাথে তুলনা করার চেষ্টা করেছি) একটি জিইউডি প্রাথমিক কী সহ newsequentialid()একটি টেবিল এবং ধারাবাহিকভাবে একটি আইএনটি প্রাথমিক কী দিয়ে একটি টেবিলটি ধারাবাহিকভাবে আরম্ভ করা হয়েছিল identity(1,1)। আমি প্রত্যাশা করবো যে সংখ্যার ছোট প্রস্থের কারণে পরবর্তীগুলি দ্রুততর হবে এবং এটি অনুক্রমিক জিইউডির তুলনায় ক্রমিক পূর্ণসংখ্যার উত্পাদনও সহজ বলে মনে হয়। তবে আমার আশ্চর্যের বিষয় হল, টেস্টের পূর্ণসংখ্যা কী সহ টেক্সটের INSERTs সিক্যুয়াল জিইউডি টেবিলের চেয়ে উল্লেখযোগ্যভাবে ধীর ছিল।

এটি পরীক্ষার জন্য গড় সময় ব্যবহার (এমএস) দেখায়:

NEWSEQUENTIALID()  1977
IDENTITY()         2223

কেউ কি এই ব্যাখ্যা করতে পারেন?

নিম্নলিখিত পরীক্ষাটি ব্যবহার করা হয়েছিল:

SET NOCOUNT ON

CREATE TABLE TestGuid2 (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

CREATE TABLE TestInt (Id Int NOT NULL identity(1,1) PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

DECLARE @BatchCounter INT = 1
DECLARE @Numrows INT = 100000


WHILE (@BatchCounter <= 20)
BEGIN 
BEGIN TRAN

DECLARE @LocalCounter INT = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuid2 (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @LocalCounter = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestInt (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @BatchCounter +=1
COMMIT 
END

DBCC showcontig ('TestGuid2')  WITH tableresults
DBCC showcontig ('TestInt')  WITH tableresults

SELECT batchNumber,DATEDIFF(ms,MIN(SomeDate),MAX(SomeDate)) AS [NEWSEQUENTIALID()]
FROM TestGuid2
GROUP BY batchNumber

SELECT batchNumber,DATEDIFF(ms,MIN(SomeDate),MAX(SomeDate)) AS [IDENTITY()]
FROM TestInt
GROUP BY batchNumber

DROP TABLE TestGuid2
DROP TABLE TestInt

আপডেট: একটি টিএমপি টেবিলের উপর ভিত্তি করে সন্নিবেশ সম্পাদনের জন্য স্ক্রিপ্টটি পরিবর্তন করা, যেমন ফিল স্যান্ডলার, মিচ হুইট এবং মার্টিনের নীচের উদাহরণগুলির মতো আমিও দেখতে পেয়েছি যে পরিচয়টি যেমন হওয়া উচিত তত দ্রুত। তবে এটি সারিগুলি সন্নিবেশ করার প্রচলিত উপায় নয় এবং আমি এখনও বুঝতে পারি না কেন পরীক্ষাটি প্রথমে ভুল হয়েছিল: এমনকি আমি আমার মূল উদাহরণ থেকে GETDATE () বাদ দিলেও পরিচয় () এখনও ধীরে ধীরে ধীর। সুতরাং দেখে মনে হচ্ছে যে NEWSEQUENTIALID () কে অস্থায়ী টেবিলে সন্নিবেশ করানোর জন্য সারিগুলি প্রস্তুত করা এবং এই টেম্প টেবিলটি ব্যবহার করে ব্যাচ-সন্নিবেশ হিসাবে অনেকগুলি সন্নিবেশ সম্পাদন করা হল পরিচয় () কে আউটপরম করার একমাত্র উপায়। সর্বোপরি, আমি মনে করি না যে আমরা ঘটনার কোনও ব্যাখ্যা পেয়েছি এবং পরিচয় () এখনও বেশিরভাগ ব্যবহারিক ব্যবহারের জন্য ধীর বলে মনে হচ্ছে। কেউ কি এই ব্যাখ্যা করতে পারেন?


4
কেবলমাত্র একটি চিন্তার বিষয়: টেবিলের সাথে জড়িত না হয়ে কোনও নতুন জিআইডি উত্পন্ন করা যেতে পারে, তবে পরবর্তী উপলব্ধ পরিচয় মানটি দুটি থ্রেড / সংযোগগুলি একই মান পাবে না তা নিশ্চিত করার জন্য অস্থায়ীভাবে এক ধরণের লককে পরিচয় করিয়ে দেয়? আমি সত্যিই অনুমান করছি। মজার প্রশ্ন!
ক্রুদ্ধ ব্যক্তি

4
কে বলে ?? তাদের প্রচুর প্রমাণ নেই - তারা দেখুন কিম্বারলি ট্রিপের ডিস্কের জায়গাটি সস্তা - এটি মূল বিষয় নয় ! ব্লগ পোস্ট - তিনি বেশ বিস্তৃত পর্যালোচনা করেন এবং INT IDENTITY
জিইউইডিগুলি

2
ঠিক আছে, উপরের পরীক্ষাটি বিপরীতটি দেখায় এবং ফলাফলগুলি পুনরাবৃত্তিযোগ্য।
নাম

2
ব্যবহারের IDENTITYজন্য কোনও টেবিল লক লাগবে না। ধারণাগতভাবে আমি দেখতে পেয়েছি আপনি এটি MAX (id) + 1 নিচ্ছেন বলে আশা করতে পারেন, কিন্তু বাস্তবে পরবর্তী মানটি সঞ্চিত রয়েছে। এটি পরবর্তী জিইউইডি খুঁজে পাওয়ার চেয়ে দ্রুত হওয়া উচিত।

4
এছাড়াও, সম্ভবত সম্ভবত টেস্টগুইড 2 টেবিলের জন্য ফিলার কলামটি সারিগুলির সমান আকার করতে CHAR (88) হওয়া উচিত
মিচ গম

উত্তর:


19

GETDATE () কল করার প্রভাবটি মুছে ফেলার জন্য আমি @ ফিল স্যান্ডলারের কোডটি সংশোধন করেছি (এতে হার্ডওয়ারের প্রভাব / বাধা থাকতে পারে ??), এবং সারিগুলি একই দৈর্ঘ্যে তৈরি করা হয়েছে।

[এসকিউএল সার্ভার 2000 সাল থেকে সময় সংক্রান্ত সমস্যা এবং উচ্চ-রেজোলিউশন টাইমার সম্পর্কিত অনেক নিবন্ধ রয়েছে, তাই আমি সেই প্রভাবটি হ্রাস করতে চেয়েছিলাম]]

প্রয়োজনীয় তথ্যগুলির চেয়ে উভয় আকারের ডেটা এবং লগ ফাইল সহ সহজ পুনরুদ্ধারের মডেলটিতে, সময়গুলি (সেকেন্ডে) এখানে রয়েছে: (নীচের সঠিক কোডের ভিত্তিতে নতুন ফলাফলের সাথে আপডেট হয়েছে)

       Identity(s)  Guid(s)
       ---------    -----
       2.876        4.060    
       2.570        4.116    
       2.513        3.786   
       2.517        4.173    
       2.410        3.610    
       2.566        3.726
       2.376        3.740
       2.333        3.833
       2.416        3.700
       2.413        3.603
       2.910        4.126
       2.403        3.973
       2.423        3.653
    -----------------------
Avg    2.650        3.857
StdDev 0.227        0.204

ব্যবহৃত কোড:

SET NOCOUNT ON

CREATE TABLE TestGuid2 (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(88))

CREATE TABLE TestInt (Id Int NOT NULL identity(1,1) PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

DECLARE @Numrows INT = 1000000

CREATE TABLE #temp (Id int NOT NULL Identity(1,1) PRIMARY KEY, rowNum int, adate datetime)

DECLARE @LocalCounter INT = 0

--put rows into temp table
WHILE (@LocalCounter < @NumRows)
BEGIN
    INSERT INTO #temp(rowNum, adate) VALUES (@LocalCounter, GETDATE())
    SET @LocalCounter += 1
END

--Do inserts using GUIDs
DECLARE @GUIDTimeStart DateTime = GETDATE()
INSERT INTO TestGuid2 (SomeDate, batchNumber) 
SELECT adate, rowNum FROM #temp
DECLARE @GUIDTimeEnd  DateTime = GETDATE()

--Do inserts using IDENTITY
DECLARE @IdTimeStart DateTime = GETDATE()
INSERT INTO TestInt (SomeDate, batchNumber) 
SELECT adate, rowNum FROM #temp
DECLARE @IdTimeEnd DateTime = GETDATE()

SELECT DATEDIFF(ms, @IdTimeStart, @IdTimeEnd) AS IdTime, DATEDIFF(ms, @GUIDTimeStart, @GUIDTimeEnd) AS GuidTime

DROP TABLE TestGuid2
DROP TABLE TestInt
DROP TABLE #temp
GO

@ মার্টিনের তদন্ত পড়ার পরে, আমি উভয় ক্ষেত্রেই প্রস্তাবিত শীর্ষস্থানীয় (@ সংখ্যা) এর সাথে পুনরায় দৌড়ে এসেছি

...
--Do inserts using GUIDs
DECLARE @num INT = 2147483647; 
DECLARE @GUIDTimeStart DATETIME = GETDATE(); 
INSERT INTO TestGuid2 (SomeDate, batchNumber) 
SELECT TOP(@num) adate, rowNum FROM #temp; 
DECLARE @GUIDTimeEnd DATETIME = GETDATE();

--Do inserts using IDENTITY
DECLARE @IdTimeStart DateTime = GETDATE()
INSERT INTO TestInt (SomeDate, batchNumber) 
SELECT TOP(@num) adate, rowNum FROM #temp;
DECLARE @IdTimeEnd DateTime = GETDATE()
...

এবং এখানে সময় ফলাফল আছে:

       Identity(s)  Guid(s)
       ---------    -----
       2.436        2.656
       2.940        2.716
       2.506        2.633
       2.380        2.643
       2.476        2.656
       2.846        2.670
       2.940        2.913
       2.453        2.653
       2.446        2.616
       2.986        2.683
       2.406        2.640
       2.460        2.650
       2.416        2.720

    -----------------------
Avg    2.426        2.688
StdDev 0.010        0.032

আমি আসল বাস্তবায়ন পরিকল্পনাটি পেতে সক্ষম হইনি, কারণ কোয়েরিটি আর ফিরে আসেনি! মনে হচ্ছে একটি বাগ সম্ভবত রয়েছে। (মাইক্রোসফ্ট এসকিউএল সার্ভার 2008 আর 2 (আরটিএম) চালাচ্ছেন - 10.50.1600.1 (এক্স 64))


7
ভাল বেঞ্চমার্কিংয়ের সমালোচনামূলক উপাদানটি ঝরঝরে চিত্রিত করে: নিশ্চিত করুন যে আপনি একবারে কেবল একটি জিনিস পরিমাপ করছেন।
অ্যারোনআউট

আপনি এখানে কি পরিকল্পনা পাবেন? এটির SORTজিইউইডিগুলির জন্য কোনও অপারেটর রয়েছে?
মার্টিন স্মিথ

@ মার্টিন: হাই, আমি পরিকল্পনাগুলি পরীক্ষা করিনি (একবারে কয়েকটি জিনিস করছিলাম :))। আমি কিছুক্ষণ পরে দেখুন ...
মিচ হুইট

@ মিচ - এ সম্পর্কে কোনও প্রতিক্রিয়া? আমি বরং সন্দেহ করি যে আপনি এখানে মূল মাপছেন যা হ'ল বড় সন্নিবেশগুলির জন্য গাইডগুলি বাছাই করার সময় নেওয়া হয়েছে যা আকর্ষণীয় হলেও ওপি-র মূল প্রশ্নের উত্তর দেয় না যা অনুক্রমিক গাইডগুলি কেন একক পরিচয় কলামগুলির চেয়ে আরও ভাল সম্পাদন করেছিল? ওপির পরীক্ষায় সারি সন্নিবেশ করানো হয়।
মার্টিন স্মিথ

2
@ মিচ - যদিও আমি এটি সম্পর্কে যত বেশি চিন্তা করি তত কমই বুঝতে পারি কেন যে কেউ যেভাবে যে NEWSEQUENTIALIDকোনওভাবে ব্যবহার করতে চাইবে । এটি সূচকটিকে আরও গভীরতর করবে, ওপির ক্ষেত্রে আরও 20% ডেটা পৃষ্ঠাগুলি ব্যবহার করবে এবং মেশিনটি পুনরায় চালু না হওয়া পর্যন্ত কেবল বাড়ার নিশ্চয়তা রয়েছে যাতে একটির উপর অনেকগুলি অসুবিধা রয়েছে identity। কেবল এই ক্ষেত্রে দেখা যাচ্ছে যে ক্যোয়ারী প্ল্যান আরও একটি অপ্রয়োজনীয়তে যুক্ত করেছে!
মার্টিন স্মিথ

19

1GB আকারের ডেটা ফাইল এবং 3 জিবিতে লগ ফাইল (ল্যাপটপ মেশিন, একই ড্রাইভের উভয় ফাইল) এবং পুনরুদ্ধারের ব্যবধানটি 100 মিনিটে সেট করা (ফলাফলগুলি অনুসন্ধানের কোনও চেকপয়েন্ট এড়ানোর জন্য) সহ সহজ পুনরুদ্ধারের মডেলের একটি নতুন ডেটাবেজে একক সারিতে আপনার একই ফলাফল inserts

আমি তিনটি কেস পরীক্ষা করেছি: প্রতিটি ক্ষেত্রে আমি নীচের টেবিলগুলিতে পৃথকভাবে 100,000 সারি সন্নিবেশ করানোর 20 ব্যাচ করেছি। এই উত্তরের পুনর্বিবেচনার ইতিহাসে সম্পূর্ণ স্ক্রিপ্টগুলি পাওয়া যাবে

CREATE TABLE TestGuid
  (
     Id          UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID() PRIMARY KEY,
     SomeDate    DATETIME, batchNumber BIGINT, FILLER CHAR(100)
  )

CREATE TABLE TestId
  (
     Id          Int NOT NULL identity(1, 1) PRIMARY KEY,
     SomeDate    DATETIME, batchNumber BIGINT, FILLER CHAR(100)
  )

CREATE TABLE TestInt
  (
     Id          Int NOT NULL PRIMARY KEY,
     SomeDate    DATETIME, batchNumber BIGINT, FILLER  CHAR(100)
  )  

তৃতীয় সারণির জন্য পরীক্ষাগুলি একটি বর্ধনশীল Idমান সহ সারিগুলি সন্নিবেশ করানো হয়েছে তবে এটি একটি লুপের মধ্যে একটি ভেরিয়েবলের মান বাড়িয়ে নিজেই গণনা করা হয়েছিল।

20 টি ব্যাচ জুড়ে নেওয়া সময়ের গড় ফলাফল নিম্নলিখিত ফলাফল দিয়েছে।

NEWSEQUENTIALID() IDENTITY()  INT
----------------- ----------- -----------
1999              2633        1878

উপসংহার

সুতরাং identityফলাফলের জন্য দায়ী যে এটি অবশ্যই প্রক্রিয়াটির ওভারহেড হিসাবে উপস্থিত রয়েছে । স্ব-গণনাযুক্ত ইনক্রিমেন্টিং পূর্ণসংখ্যার জন্য ফলাফলগুলি কেবলমাত্র আইও ব্যয়ের বিষয়ে বিবেচনা করার সময় কী প্রত্যাশা করা হবে তার সাথে মিলিত হয়।

আমি যখন সঞ্চিত পদ্ধতিতে উপরে বর্ণিত সন্নিবেশ কোডটি রাখি এবং পর্যালোচনা sys.dm_exec_procedure_statsকরি তবে এটি নীচের ফলাফলগুলি দেয়

proc_name      execution_count      total_worker_time    last_worker_time     min_worker_time      max_worker_time      total_elapsed_time   last_elapsed_time    min_elapsed_time     max_elapsed_time     total_physical_reads last_physical_reads  min_physical_reads   max_physical_reads   total_logical_writes last_logical_writes  min_logical_writes   max_logical_writes   total_logical_reads  last_logical_reads   min_logical_reads    max_logical_reads
-------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- -------------------- --------------------
IdentityInsert 20                   45060360             2231067              2094063              2645079              45119362             2234067              2094063              2660080              0                    0                    0                    0                    32505                1626                 1621                 1626                 6268917              315377               276833               315381
GuidInsert     20                   34829052             1742052              1696051              1833055              34900053             1744052              1698051              1838055              0                    0                    0                    0                    35408                1771                 1768                 1772                 6316837              316766               298386               316774

সুতরাং সেই ফলাফলগুলিতে total_worker_timeপ্রায় 30% বেশি। এটি প্রতিনিধিত্ব করে

সংকলিত হওয়ার পর থেকে মাইক্রোসেকেন্ডে সিপিইউর মোট পরিমাণ, যা এই সঞ্চিত প্রক্রিয়াটির দ্বারা কার্যকর হয়েছিল।

সুতরাং এটি সহজেই উপস্থিত হয় যেমন IDENTITYমান উত্পন্ন কোডটি যেটি উত্পন্ন করে তার চেয়ে বেশি সিপিইউ NEWSEQUENTIALID()নিবিড়তর হয় (2 চিত্রের মধ্যে পার্থক্য 10231308 যা প্রতি সন্নিবেশে প্রায় 5µs গড় হয়) এবং এই টেবিল সংজ্ঞাটির জন্য এই নির্দিষ্ট সিপিইউ খরচ হয় কীটির বৃহত্তর প্রস্থের কারণে অতিরিক্ত লজিকাল রিডস ও অ্যালার্জিকে ছাড়িয়ে যাওয়ার পর্যাপ্ত পরিমাণ ছিল। (এনবি: ইটজিক বেন গা এখানে এখানে একই রকম পরীক্ষা করেছেন এবং প্রতি সন্নিবেশে 2% জরিমানা খুঁজে পেয়েছেন)

তাহলে কেন IDENTITYবেশি সিপিইউ নিবিড় UuidCreateSequential?

আমি বিশ্বাস করি এটি এই নিবন্ধে ব্যাখ্যা করা হয়েছেidentityউত্পন্ন প্রতিটি দশম মানের জন্য, এসকিউএল সার্ভারকে ডিস্কের সিস্টেমে সারণিতে পরিবর্তন লিখতে হবে

মাল্টিআরউ সন্নিবেশ সম্পর্কে কী?

যখন এক লক্ষ বিবরণীতে ১০০,০০০ সারি সন্নিবেশ করা হয়েছে তখন আমি দেখলাম পার্থক্যটি অদৃশ্য হয়ে গেছে সম্ভবত GUIDমামলার সামান্য উপকারের সাথে তবে পরিষ্কার কাট ফলাফল হিসাবে কোথাও নেই। আমার টেস্টে 20 টি ব্যাচের গড় ছিল

NEWSEQUENTIALID() IDENTITY()
----------------- -----------
1016              1088

ফিলের কোডে এবং মিচের ফলাফলের প্রথম সেটটিতে এটি পেনাল্টিটি প্রকাশিত না হওয়ার কারণ হ'ল এমনটি ঘটেছিল যে কোডটি আমি বহু সারি সন্নিবেশ করানোর জন্য ব্যবহার করি SELECT TOP (@NumRows)। এটি isোকানো হবে এমন সারিগুলির সংখ্যা সঠিকভাবে অনুমান করা থেকে অপটিমাস্টারকে বাধা দিয়েছে।

এটি সুবিধাজনক বলে মনে হচ্ছে কারণ এখানে একটি নির্দিষ্ট টিপিং পয়েন্ট রয়েছে যা এটি (অনুমিত অনুক্রমিক!) GUIDএর জন্য একটি অতিরিক্ত সাজানোর ক্রিয়াকলাপ যোগ করবে ।

জিইউডি বাছাই করুন

বিএল-এর বর্ণনামূলক পাঠ্য থেকে এই সাজানোর ক্রিয়াকলাপের প্রয়োজন নেই ।

উইন্ডোজ শুরু হওয়ার পর থেকে একটি নির্দিষ্ট কম্পিউটারে এই ফাংশনটি দ্বারা উত্পাদিত যে কোনও জিইউডি এর চেয়ে বেশি এমন একটি জিইউডি তৈরি করে। উইন্ডোজ পুনঃসূচনা করার পরে, জিইউডিটি নিম্ন সীমার থেকে আবার শুরু করতে পারে, তবে এখনও বিশ্বব্যাপী অনন্য।

সুতরাং এটি আমার কাছে একটি ত্রুটি বা অনুপস্থিত অপ্টিমাইজেশান বলে মনে হয়েছিল যে এসকিউএল সার্ভার স্বীকৃতি দেয় না যে এটি গণনা স্কেলারের আউটপুট ইতিমধ্যে identityকলামটির জন্য আগে থেকেই সাজানো থাকবে । ( সম্পাদনা আমি এটি রিপোর্ট করেছি এবং অযৌক্তিক সাজানোর সমস্যাটি এখন ডেনালিতে স্থির হয়েছে )


এটি পুরোপুরি প্রভাব ফেলেছে তা নয় তবে কেবল স্পষ্টতার স্বার্থে ডেনি উদ্ধৃত সংখ্যা, 20 টি ক্যাশেড পরিচয় মান ভুল রয়েছে - এটি 10 ​​হওয়া উচিত
অ্যারন বারট্রান্ড

@ অ্যারোনবার্ট্র্যান্ড - ধন্যবাদ আপনি যে নিবন্ধটি সংযুক্ত করেছেন এটি সর্বাধিক তথ্যবহুল।
মার্টিন স্মিথ

8

বেশ সহজ: জিইউডির সাথে, পরিচয়ের জন্য লাইনের পরবর্তী নম্বরটি উত্পন্ন করা সস্তা (জিইউডিটির বর্তমান মান সংরক্ষণ করতে হবে না, পরিচয়টি থাকতে হবে)। এমনকি NEWSEQUENTIALGUID এর জন্যও এটি সত্য।

আপনি পরীক্ষাটি আরও সুষ্ঠু করতে পারেন এবং একটি বৃহত CACHE সহ একটি সিকোয়েন্সার ব্যবহার করতে পারেন - এটি পরিচয়ের চেয়ে সস্তা।

তবে এমআর যেমন বলেছেন, জিইউইডিগুলির কিছু বড় সুবিধা রয়েছে। প্রকৃতপক্ষে, তারা পরিচয় কলামগুলির তুলনায় অনেক বেশি স্কেলযোগ্য (তবে কেবল তারা ক্রমিক নয়)।

দেখুন: http://blog.kejser.org/2011/10/05/boosting-insert-speed-by-generating-scalable-keys/


আমি মনে করি আপনি মিস করেছেন যে তারা অনুক্রমিক নির্দেশিকা ব্যবহার করছে।
মার্টিন স্মিথ

মার্টিন: যুক্তিটি অনুক্রমিক জিইউইডি-র পক্ষেও সত্য। পরিচয় সংরক্ষণ করতে হবে (পুনরায় আরম্ভের পরে তাদের পুরানো মানটিতে ফিরে যেতে), অনুক্রমিক জিইউডিটির এই সীমাবদ্ধতা নেই।
থমাস কেজার

2
হ্যাঁ আমার মন্তব্যের পরে উপলব্ধি হয়ে গেছে আপনি স্মৃতিতে সঞ্চয় করার চেয়ে অবিচ্ছিন্নভাবে সংরক্ষণ করার কথা বলছিলেন। 2012 IDENTITYযদিও এর জন্য একটি ক্যাশে ব্যবহার করে । অতএব অভিযোগ এখানে
মার্টিন স্মিথ

4

আমি এই ধরণের প্রশ্নে মুগ্ধ। কেন আপনি একটি শুক্রবার রাতে পোস্ট করতে হয়েছিল? :)

আমি মনে করি এমনকি যদি আপনার পরীক্ষাটি কেবল ইনসার্ট কর্মক্ষমতা পরিমাপের উদ্দেশ্যে করা হয় তবে আপনি (ল) বিভ্রান্তিকর হতে পারে এমন অনেকগুলি উপাদান চালু করতে পারেন (লুপিং, দীর্ঘমেয়াদি লেনদেন ইত্যাদি))

আমার সংস্করণটি কিছু প্রমাণিত হয়েছে তা আমি সম্পূর্ণরূপে নিশ্চিত নই, তবে পরিচয় এটির জিআইডি গুলির চেয়ে ভাল পারফর্ম করতে পারে (একটি হোম পিসিতে ৩.২ সেকেন্ড বনাম 8.৮ সেকেন্ড):

SET NOCOUNT ON

CREATE TABLE TestGuid2 (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

CREATE TABLE TestInt (Id Int NOT NULL identity(1,1) PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

DECLARE @Numrows INT = 1000000

CREATE TABLE #temp (Id int NOT NULL Identity(1,1) PRIMARY KEY, rowNum int)

DECLARE @LocalCounter INT = 0

--put rows into temp table
WHILE (@LocalCounter < @NumRows)
BEGIN
    INSERT INTO #temp(rowNum) VALUES (@LocalCounter)
    SET @LocalCounter += 1
END

--Do inserts using GUIDs
DECLARE @GUIDTimeStart DateTime = GETDATE()
INSERT INTO TestGuid2 (SomeDate, batchNumber) 
SELECT GETDATE(), rowNum FROM #temp
DECLARE @GUIDTimeEnd  DateTime = GETDATE()

--Do inserts using IDENTITY
DECLARE @IdTimeStart DateTime = GETDATE()
INSERT INTO TestInt (SomeDate, batchNumber) 
SELECT GETDATE(), rowNum FROM #temp
DECLARE @IdTimeEnd DateTime = GETDATE()

SELECT DATEDIFF(ms, @IdTimeStart, @IdTimeEnd) AS IdTime
SELECT DATEDIFF(ms, @GUIDTimeStart, @GUIDTimeEnd) AS GuidTime

DROP TABLE TestGuid2
DROP TABLE TestInt
DROP TABLE #temp

অন্য যে বিষয়টির কথা কেউ উল্লেখ করেনি তা হ'ল ডাটাবেস পুনরুদ্ধার মডেল, এবং লগ ফাইলের বৃদ্ধি ...
মিচ হুইট

@ প্রয়োজনীয় যা প্রয়োজন তার চেয়ে বড় আকারের ডেটা এবং লগ ফাইলের সাথে সহজ পুনরুদ্ধারের মডেলটিতে একটি নতুন ডাটাবেসে মিচ করুন আমি ওপি-তে একই জাতীয় ফলাফল পেয়েছি।
মার্টিন স্মিথ

আমি পরিচয়ের জন্য মাত্র 2.560 সেকেন্ডের সময় পেয়েছি, এবং গাইডের জন্য 3.666 সেকেন্ড (প্রয়োজনীয় পুনরুদ্ধার মডেলের সাথে ডেটা এবং লগ ফাইল উভয় আকারের প্রয়োজন অনুসারে)
মিচ হুইট

@ মিচ - সবগুলি একই লেনদেনে বা ফিলের কোডে ওপির কোডে?
মার্টিন স্মিথ

এই পোস্টার কোডে, আমি এখানে মন্তব্য করছি কেন। আমি ব্যবহৃত
কোডটিও

3

আমি আপনার নমুনা স্ক্রিপ্টটি কয়েকবার ব্যাচের গণনা এবং আকারের জন্য কয়েকটি টুইটগুলি চালিয়েছি (এবং এটি সরবরাহ করার জন্য আপনাকে অনেক ধন্যবাদ)।

প্রথমে আমি বলব যে আপনি কীগুলির কার্য সম্পাদন - INSERTগতির দিকটি একবার মাত্র পরিমাপ করছেন । সুতরাং যতক্ষণ না আপনি কেবলমাত্র টেবিলগুলিতে যত তাড়াতাড়ি সম্ভব ডেটা পাওয়ার সাথে বিশেষভাবে উদ্বিগ্ন হন এই প্রাণীর আরও অনেক কিছু।

আমার অনুসন্ধানগুলি আপনার মত সাধারণভাবে ছিল। যাইহোক, আমি উল্লেখ করব যে INSERTগতির মধ্যে পরিবর্তন ( GUIDএবং IDENTITY) এর সাথে তুলনায় কিছুটা বড় - সম্ভবত রানের মধ্যে +/- 10%। ব্যাচগুলি প্রতিবার 2 - 3% এর চেয়ে কম পরিবর্তিত হয়।GUIDIDENTITYIDENTITY

এছাড়াও লক্ষণীয়, আমার পরীক্ষার বাক্সটি আপনার চেয়ে পরিষ্কারভাবে কম শক্তিশালী তাই আমাকে আরও ছোট সারি সংখ্যা ব্যবহার করতে হয়েছিল।


পিকে যখন একটি জিআইডি হয় তখন কি সম্ভব যে ইঞ্জিনটি কোনও রেকর্ডের শারীরিক অবস্থান নির্ধারণের জন্য একটি সূচক নয় বরং একটি হ্যাশিং অ্যালগরিদম ব্যবহার করে? হ্যাশড প্রাথমিক কীগুলির সাথে একটি বিচ্ছিন্ন টেবিলের সন্নিবেশগুলি সূচক ওভারহেডের অনুপস্থিতির কারণে প্রাথমিক কীতে একটি সূচী সহ একটি টেবিলের মধ্যে সন্নিবেশের চেয়ে সবসময় দ্রুত হয়। এটি কেবল একটি প্রশ্ন - উত্তরটি যদি না হয় তবে আমাকে ভোট দিন না কেবল কর্তৃপক্ষের লিঙ্কটি সরবরাহ করুন।

1

আমি এই একই বিষয়ের জন্য স্ট্যাকওভারফ্লোতে অন্য এক সমালোচককে আবার উল্লেখ করতে যাচ্ছি - https://stackoverflow.com

একটি জিনিস আমি জানি যে অনুক্রমিক জিইউইডি থাকা হ'ল খুব কম পাতার গতিবিধির কারণে সূচির ব্যবহার আরও ভাল এবং এর ফলে এইচডি অনুসন্ধানকে হ্রাস করা যায়। আমি এটির কারণেই ভাবব, সন্নিবেশগুলি দ্রুততর হবে, কারণ এতে বৃহত সংখ্যক পৃষ্ঠাগুলির উপর কীগুলি বিতরণ করতে হবে না।

আমার ব্যক্তিগত অভিজ্ঞতা হ'ল আপনি যখন একটি বৃহত উচ্চ ট্রাফিক ডিবি বাস্তবায়ন করছেন তখন জিইউইডিগুলি ব্যবহার করা ভাল, কারণ এটি অন্যান্য সিস্টেমের সাথে সংহতকরণের জন্য এটি আরও বেশি স্কেলযোগ্য করে তোলে। এটি প্রতিলিপি, বিশেষত এবং অন্ত: বিগিন্ট সীমা .... এর জন্য নয় যে আপনি বিগিন্টের বাইরে চলে যাবেন না, তবে শেষ পর্যন্ত আপনি যাবেন এবং ফিরে আসবেন back


1
আপনি বিগআইএনটিএস থেকে চালাবেন না, কখনও ... এটি দেখুন: sqlmag.com/blog/it-possible-run-out-bigint-values
টমাস কেজার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.