এসকিউএল সার্ভার ২০০৮ এবং তার বেশি
এসকিউএল সার্ভার ২০০৮ এবং তারপরে অবশ্যই সবচেয়ে দ্রুততম উপায় Convert(date, @date)
। এটি একটি datetime
বা datetime2
প্রয়োজনে আবার কাস্ট করা যেতে পারে ।
এসকিউএল সার্ভার ২০০৫ এবং এর থেকেও পুরনো ক্ষেত্রে সত্যিই সেরা কী?
এসকিউএল সার্ভারে একটি তারিখ থেকে সময় কেটে নেওয়ার জন্য দ্রুততম সম্পর্কে কী অসঙ্গত দাবিগুলি দেখেছি এবং কিছু লোক এমনকি তারা বলেছিল যে তারা পরীক্ষা করেছে তবে আমার অভিজ্ঞতাটি অন্যরকম হয়েছে। সুতরাং আসুন আমরা আরও কিছু কঠোর পরীক্ষা করি এবং প্রত্যেকের কাছে স্ক্রিপ্ট থাকি যাতে আমি যদি কোনও ভুল করি তবে লোকেরা আমাকে সংশোধন করতে পারে।
ফ্লোট রূপান্তরগুলি সঠিক নয়
প্রথমত, আমি রূপান্তর datetime
করা থেকে দূরে থাকব float
, কারণ এটি সঠিকভাবে রূপান্তর করে না। আপনি সঠিকভাবে সময় অপসারণ জিনিস সঙ্গে কাজ পেতে পারে, কিন্তু আমি মনে করি এটা একটি খারাপ ধারণা করা হয়েছে কারণ এটি পরোক্ষভাবে বিকাশকারীদের কাছে যোগাযোগ করে যে এই একটি নিরাপদ অপারেশন হয় এবং এটি ব্যবহার করবেন তা তা না হয় । এক নজর দেখে নাও:
declare @d datetime;
set @d = '2010-09-12 00:00:00.003';
select Convert(datetime, Convert(float, @d));
এটি আমাদের কোড বা আমাদের উদাহরণগুলিতে লোকদের শেখানো উচিত এমন কিছু নয়।
এছাড়াও, এটি এমনকি দ্রুততম উপায়ও নয়!
প্রুফ - পারফরম্যান্স টেস্টিং
বিভিন্ন পদ্ধতি কীভাবে সত্যিই সজ্জিত হয় তা দেখতে আপনি যদি কিছু পরীক্ষা নিজেই করতে চান তবে পরীক্ষা আরও দূরে চালানোর জন্য আপনার এই সেটআপ স্ক্রিপ্টের প্রয়োজন হবে:
create table AllDay (Tm datetime NOT NULL CONSTRAINT PK_AllDay PRIMARY KEY CLUSTERED);
declare @d datetime;
set @d = DateDiff(Day, 0, GetDate());
insert AllDay select @d;
while @@ROWCOUNT != 0
insert AllDay
select * from (
select Tm =
DateAdd(ms, (select Max(DateDiff(ms, @d, Tm)) from AllDay) + 3, Tm)
from AllDay
) X
where Tm < DateAdd(Day, 1, @d);
exec sp_spaceused AllDay;
দয়া করে নোট করুন যে এটি আপনার ডাটাবেসে একটি 427.57 মেগাবাইট সারণী তৈরি করে এবং এটি চালাতে 15-30 মিনিটের মতো কিছু লাগবে। আপনার ডাটাবেস যদি ছোট হয় এবং 10% প্রবৃদ্ধিতে সেট করা থাকে তবে আপনি যদি প্রথমে যথেষ্ট বড় আকারের হন তবে এটি বেশি সময় নেয়।
এখন প্রকৃত কর্মক্ষমতা পরীক্ষার স্ক্রিপ্টের জন্য। দয়া করে মনে রাখবেন যে ক্লায়েন্টের কাছে সারিগুলি ফিরিয়ে না দেওয়া উদ্দেশ্যমূলক কারণ এটি 26 মিলিয়ন সারিগুলিতে ব্যয়বহুল এবং পদ্ধতিগুলির মধ্যে পারফরম্যান্সের পার্থক্যগুলি লুকিয়ে রাখে।
কর্মক্ষমতা ফলাফল
set statistics time on;
GO
declare
@dd date,
@d datetime,
@di int,
@df float,
@dv varchar(10);
select @d = CONVERT(date, Tm) from AllDay;
select @d = CAST(Tm - 0.50000004 AS int) from AllDay;
select @d = DATEDIFF(DAY, 0, Tm) from AllDay;
select @d = FLOOR(CAST(Tm as float)) from AllDay;
select @d = CONVERT(VARCHAR(8), Tm, 112) from AllDay;
select @d = CONVERT(CHAR(8), Tm, 112) from AllDay;
select @d = CONVERT(VARCHAR(10), Tm, 101) from AllDay;
select @dd = Tm from AllDay;
select @di = CAST(Tm - 0.50000004 AS int) from AllDay;
select @di = DATEDIFF(DAY, 0, Tm) from AllDay;
select @df = FLOOR(CAST(Tm as float)) from AllDay;
select @dv = CONVERT(VARCHAR(8), Tm, 112) from AllDay;
select @dv = CONVERT(CHAR(8), Tm, 112) from AllDay;
select @dv = CONVERT(VARCHAR(10), Tm, 101) from AllDay;
GO
set statistics time off;
কিছু র্যাম্বলিং বিশ্লেষণ
এই সম্পর্কে কিছু নোট। প্রথমত, যদি কেবল গ্রুপ বা কোনও তুলনা সম্পাদন করা হয় তবে এগুলিতে আবার রূপান্তর করার দরকার নেই datetime
। সুতরাং আপনি এড়াতে কিছু সিপিইউ সংরক্ষণ করতে পারেন, যদি না আপনি প্রদর্শনের উদ্দেশ্যে চূড়ান্ত মান প্রয়োজন হয়। আপনি রূপান্তরিত মান দ্বারা গ্রুপও করতে পারেন এবং রূপান্তরটি কেবল নির্বাচন বিভাগে রাখতে পারেন:
select Convert(datetime, DateDiff(dd, 0, Tm))
from (select '2010-09-12 00:00:00.003') X (Tm)
group by DateDiff(dd, 0, Tm)
এছাড়াও, দেখুন কীভাবে সংখ্যার রূপান্তরগুলি পুনরায় রূপান্তর করতে কেবল আরও কিছুটা সময় নেয় datetime
, তবেvarchar
রূপান্তরটি প্রায় দ্বিগুণ হয়? এটি সিপিইউর অংশটি প্রকাশ করে যা কোয়েরিতে তারিখ গণনার জন্য উত্সর্গীকৃত। সিপিইউ ব্যবহারের কিছু অংশ রয়েছে যা তারিখ গণনা জড়িত না এবং এটি উপরের প্রশ্নের মধ্যে 19875 এমএসের কাছাকাছি কিছু বলে মনে হচ্ছে। তারপরে রূপান্তরটি কিছু অতিরিক্ত পরিমাণ নেয়, সুতরাং যদি দুটি রূপান্তর হয় তবে সেই পরিমাণটি প্রায় দ্বিগুণ ব্যবহৃত হয়।
আরও পরীক্ষা করে দেখা যায় যে তুলনায় Convert(, 112)
, Convert(, 101)
ক্যোয়ারিতে কিছু অতিরিক্ত সিপিইউ ব্যয় হয়েছে (যেহেতু এটি দীর্ঘ ব্যবহার করে varchar
?), কারণ দ্বিতীয় রূপান্তরটি date
প্রাথমিক রূপান্তর হিসাবে তত বেশি ব্যয় করে না varchar
, তবে Convert(, 112)
এটি একই 20000 এর কাছাকাছি রয়েছে এমএস সিপিইউ বেস ব্যয়।
আমি উপরের বিশ্লেষণের জন্য সিপিইউ সময়ে সেই গণনাগুলি ব্যবহার করেছি:
method round single base
date 21324 19891 18458
int 23031 21453 19875
datediff 23782 23218 22654
float 36891 29312 21733
varchar-112 102984 64016 25048
varchar-101 123375 65609 7843
রাউন্ডটি ফিরে আসার জন্য রাউন্ড ট্রিপের সিপিইউ সময় datetime
।
একক হ'ল সিপিইউ সময় হ'ল একক রূপান্তর করার জন্য বিকল্প ডেটা টাইপ (সময় অংশ অপসারণের পার্শ্ব প্রতিক্রিয়া রয়েছে এমন এক)।
বেস থেকে বিয়োগ হিসাব হয় single
দুই আমন্ত্রণ মধ্যে পার্থক্য: single - (round - single)
। এটি একটি বলপার্ক চিত্র যা এই ডেটা টাইপ এবং datetime
এ থেকে রূপান্তর অনুমান করে এবং উভয় দিক থেকেই প্রায় একই। এটি প্রদর্শিত হয় এই অনুমানটি নিখুঁত নয় তবে নিকটে কারণ মানগুলি কেবলমাত্র একটি ব্যতিক্রম সহ 20000 এমএসের নিকটে।
আরও একটি আকর্ষণীয় বিষয় হ'ল বেস ব্যয়টি একক Convert(date)
পদ্ধতির প্রায় সমান (যা প্রায় 0 ব্যয় হতে হবে, কারণ সার্ভারটি অভ্যন্তরীণভাবে datetime
ডেটা টাইপের প্রথম চারটি বাইটের মধ্যে পূর্ণসংখ্যার দিনের অংশটি বের করতে পারে )।
উপসংহার
সুতরাং এটি দেখতে যা দেখায় তা হ'ল একক দিকের varchar
রূপান্তর পদ্ধতিটি প্রায় 1.8 takes সেবন করে এবং একক দিকের DateDiff
পদ্ধতিটি প্রায় 0.18 takes সেবন করে। আমি 18458 এমএস মোট 25,920,000 সারির জন্য আমার পরীক্ষার সময় সবচেয়ে রক্ষণশীল "বেস সিপিইউ" এর উপর ভিত্তি করে চলেছি, সুতরাং 23218 এমএস / 25920000 = 0.18। সে। আপাত 10x এর উন্নতি অনেকটা মনে হয় তবে আপনি কয়েক হাজার সারি (617k সারি = 1 সেকেন্ডের সঞ্চয়) নিয়ে কাজ না করা অবধি এটি খুব সুন্দর small
এমনকি এই ক্ষুদ্র পরম উন্নতি দেওয়া, আমার মতে, DateAdd
পদ্ধতিটি জিতেছে কারণ এটি কার্য সম্পাদন এবং স্পষ্টতার সর্বোত্তম সমন্বয়। যেটির "ম্যাজিক নম্বর" এর উত্তর প্রয়োজন 0.50000004
তা কোনও দিন কাউকে কামড়ায় (পাঁচটি শূন্য বা ছয় ???), এবং এটি বোঝা আরও শক্ত।
অতিরিক্ত নোট
আমি যখন কিছুটা সময় পাই তখন আমি পরিবর্তন 0.50000004
করতে যাব '12:00:00.003'
এবং এটি কীভাবে হয় তা দেখুন। এটি একই datetime
মানতে রূপান্তরিত হয়েছে এবং আমি মনে রাখা এটি আরও সহজ মনে করি।
আগ্রহীদের জন্য, উপরোক্ত পরীক্ষাগুলি এমন একটি সার্ভারে চালানো হয়েছিল যেখানে @@ সংস্করণটি নিম্নলিখিতগুলি প্রদান করে:
মাইক্রোসফ্ট এসকিউএল সার্ভার ২০০৮ (আরটিএম) - 10.0.1600.22 (ইন্টেল এক্স 86) জুলাই 9 2008 14:43:34 কপিরাইট (সি) 1988-2008 উইন্ডোজ এনটি 5.2 তে মাইক্রোসফ্ট কর্পোরেশন স্ট্যান্ডার্ড সংস্করণ (বিল্ড 3790: সার্ভিস প্যাক 2)