ভারচার (255) এর সাথে তুলনা করে ভারচার (5000) ব্যবহার করা কি খারাপ হবে?


28

যেহেতু varcharযাই হোক না কেন গতিশীলভাবে স্থান বরাদ্দ করা হয়, আমার প্রশ্নটি হ'ল ব্যবহারের varchar(255)তুলনায় আরও দক্ষ হওয়া বা বেশি স্থান সংরক্ষণ করা varchar(5000)। যদি হ্যাঁ, কেন?


আপনার কি 5000 ক্যারেক্টার প্রশস্ত কলাম দরকার? যদি তাই হয় কেন? একটি ভারচার (ম্যাক্স) কলামটি কি এখানে আপনার জন্য আরও ভাল কাজ করতে পারে?
রিচার্ড এল ডসন

উত্তর:


52

হ্যাঁ, এর varchar(5000)চেয়ে খারাপ আরও হতে পারে varchar(255)যদি সমস্ত মানগুলি পরে থাকে। কারণটি হ'ল এসকিউএল সার্ভার ডেটা আকার এবং পরিবর্তে, একটি সারণীতে কলামগুলির ঘোষিত ( প্রকৃত নয় ) আকারের ভিত্তিতে মেমরি অনুদান অনুমান করবে । আপনার কাছে থাকলে varchar(5000)এটি ধরে নেওয়া হবে যে প্রতিটি মান 2,500 অক্ষর দীর্ঘ, এবং এর উপর ভিত্তি করে মেমরি সংরক্ষণ করে।

খারাপ অভ্যাস সম্পর্কে আমার সাম্প্রতিক গ্রুপপাই উপস্থাপনা থেকে এখানে একটি ডেমো দেওয়া হয়েছে যা নিজের পক্ষে প্রমাণ করা সহজ করে তোলে (কিছু sys.dm_exec_query_statsআউটপুট কলামের জন্য এসকিউএল সার্ভার 2016 প্রয়োজন , তবে এখনও SET STATISTICS TIME ONপূর্ববর্তী সংস্করণগুলিতে বা অন্য সরঞ্জামগুলির সাথে প্রমাণযোগ্য হওয়া উচিত ); এটি একই ডেটার বিপরীতে একই ক্যোয়ারির জন্য বৃহত্তর মেমরি এবং দীর্ঘ রানটাইম দেখায় - কেবলমাত্র পার্থক্যটি কলামগুলির ঘোষিত আকার:

-- create three tables with different column sizes
CREATE TABLE dbo.t1(a nvarchar(32),   b nvarchar(32),   c nvarchar(32),   d nvarchar(32));
CREATE TABLE dbo.t2(a nvarchar(4000), b nvarchar(4000), c nvarchar(4000), d nvarchar(4000));
CREATE TABLE dbo.t3(a nvarchar(max),  b nvarchar(max),  c nvarchar(max),  d nvarchar(max));
GO -- that's important

-- Method of sample data pop : irrelevant and unimportant.
INSERT dbo.t1(a,b,c,d)
  SELECT TOP (5000) LEFT(name,1), RIGHT(name,1), ABS(column_id/10), ABS(column_id%10)
  FROM sys.all_columns ORDER BY object_id;
GO 100
INSERT dbo.t2(a,b,c,d) SELECT a,b,c,d FROM dbo.t1;
INSERT dbo.t3(a,b,c,d) SELECT a,b,c,d FROM dbo.t1;
GO

-- no "primed the cache in advance" tricks
DBCC FREEPROCCACHE WITH NO_INFOMSGS;
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
GO

-- Redundancy in query doesn't matter! Just has to create need for sorts etc.
GO
SELECT DISTINCT a,b,c,d, DENSE_RANK() OVER (PARTITION BY b,c ORDER BY d DESC)
FROM dbo.t1 GROUP BY a,b,c,d ORDER BY c,a DESC;
GO
SELECT DISTINCT a,b,c,d, DENSE_RANK() OVER (PARTITION BY b,c ORDER BY d DESC)
FROM dbo.t2 GROUP BY a,b,c,d ORDER BY c,a DESC;
GO
SELECT DISTINCT a,b,c,d, DENSE_RANK() OVER (PARTITION BY b,c ORDER BY d DESC)
FROM dbo.t3 GROUP BY a,b,c,d ORDER BY c,a DESC;
GO

SELECT [table] = N'...' + SUBSTRING(t.[text], CHARINDEX(N'FROM ', t.[text]), 12) + N'...', 
s.last_dop, s.last_elapsed_time, s.last_grant_kb, s.max_ideal_grant_kb
FROM sys.dm_exec_query_stats AS s CROSS APPLY sys.dm_exec_sql_text(s.sql_handle) AS t
WHERE t.[text] LIKE N'%dbo.'+N't[1-3]%' ORDER BY t.[text];

সুতরাং, হ্যাঁ, আপনার কলামগুলি ডান আকারের করুন please

এছাড়াও, আমি বার্চর (32), বর্ণচর (255), বর্ণচর (5000), বারচর (8000), এবং বর্ণচর (সর্বাধিক) দিয়ে পুনরায় পরীক্ষা চালিয়েছি। অনুরূপ ফলাফল ( প্রসারিত করতে ক্লিক করুন ), যদিও 32 এবং 255 এর মধ্যে পার্থক্য রয়েছে এবং 5000 থেকে 8,000 এর মধ্যে পার্থক্য নগণ্য ছিল:

এখানে চিত্র বর্ণনা লিখুন

TOP (5000)আরও সম্পূর্ণ পুনরুত্পাদনযোগ্য পরীক্ষার জন্য পরিবর্তনের সাথে এখানে আরও একটি পরীক্ষা দেওয়া হচ্ছে যা সম্পর্কে আমি অবিচ্ছিন্নভাবে ব্যাজার্ড হয়ে যাচ্ছিলাম ( বিস্তৃত করতে ক্লিক করুন ):

এখানে চিত্র বর্ণনা লিখুন

এমনকি 10,000 সারিগুলির পরিবর্তে 5000 সারি সহ (এবং এসআইকিউএল সার্ভার ২০০৮ আর ২ হিসাবে কমপক্ষে পিছনে sys.all_columsগুলিতে 5,000+ সারি রয়েছে), অপেক্ষাকৃত রৈখিক অগ্রগতি লক্ষ্য করা যায় - এমনকি একই ডেটা সহ, সংজ্ঞায়িত আকারটি আরও বড় কলামটির, একই একই ক্যোয়ারীটি পূরণ করার জন্য আরও মেমরি এবং সময় প্রয়োজন (এমনকি এটির অর্থহীনতা থাকলেও DISTINCT)।


এটা সত্যিই অবাক। মধ্যে পার্থক্য করবে varchar(450)এবং varchar(255)একই হতে? (বা 4000 এর নিচে কিছু?)
এ_ ঘোড়া_বিহীন_নাম_নামা

@ এ_হর্স_বিহীন_নাম_নাম আমি রানটাইম পারফরম্যান্সের সমস্ত অনুমতি পরীক্ষা করে দেখিনি, তবে মেমরি অনুদানটি একটি রৈখিক অগ্রগতি হবে - এটি কেবলমাত্র একটি কাজ rowcount*(column_size/2)
অ্যারন বার্ট্র্যান্ড

এটি তখন হতাশাব্যঞ্জক। আমি যদিও এসকিউএল সার্ভারের আধুনিক সংস্করণগুলি এতে ভুগছে না (যতক্ষণ না নির্ধারিত দৈর্ঘ্য 8000 বা 4000 এর চেয়ে কম হয়)।
a_horse_with_no_name

1
@ এ_হর্স_বিহীন_নো_নাম ঠিক আছে, ডেটাটি কত বিস্তৃত তা যাতে অনুভূতি এড়াতে পারে এ জন্য এটি অনুমান করতে হবে। এটা আর কীভাবে অনুমান করা উচিত? এক্সিকিউশন প্ল্যান তৈরির পূর্ববর্তী হিসাবে সমস্ত ভেরিয়েবল প্রস্থের কলামগুলির গড় / সর্বোচ্চ দৈর্ঘ্য নির্ধারণ করতে এটি পুরো টেবিলটি স্ক্যান করতে এবং পড়তে পারে না (এবং এটি যদি পারত তবে এটি কেবল পুনরায় সংযোগের সময় এটি করতে সক্ষম হবে)।
অ্যারন বার্ট্র্যান্ড

2
ওরাকল পরিসংখ্যান রাখে যেমন গড় সারির দৈর্ঘ্য, প্রতিটি কলামের জন্য সর্বনিম্ন এবং সর্বোচ্চ মান পাশাপাশি একটি হিস্টোগ্রাম। পোস্টগ্রিস খুব অনুরূপ পরিসংখ্যান রাখে (এটি কমপক্ষে / সর্বাধিক তবে ফ্রিকোয়েন্সি রেকর্ড করে না)। তাদের উভয়ের ক্ষেত্রে এনভারচর (১৫০), এনভারচার (২০০০) বা ভারচর (৪০০) পারফরম্যান্সে কোনও পার্থক্য নেই।
a_horse_with_no_name
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.