এসকিউএল সার্ভারের 8 কেবিট ডেটা পৃষ্ঠা থেকে 512 বাইট ব্যবহার করা হচ্ছে না


13

আমি নিম্নলিখিত সারণী তৈরি করেছি:

CREATE TABLE dbo.TestStructure
(
    id INT NOT NULL,
    filler1 CHAR(36) NOT NULL,
    filler2 CHAR(216) NOT NULL
);

এবং তারপরে একটি ক্লাস্টারড সূচক তৈরি করেছে:

CREATE CLUSTERED INDEX idx_cl_id 
ON dbo.TestStructure(id);

পরবর্তী আমি এটিকে 30 টি সারি দিয়ে পপুলেট করেছি প্রতিটি আকার 256 বাইট (টেবিল ঘোষণার ভিত্তিতে):

DECLARE @i AS int = 0;

WHILE @i < 30
BEGIN
    SET @i = @i + 1;

    INSERT INTO dbo.TestStructure (id, filler1, filler2)
    VALUES (@i, 'a', 'b');
END;

এখন "ট্রেনিং কিট (পরীক্ষা 70-461): মাইক্রোসফ্ট এসকিউএল সার্ভার 2012 (ইটজিক বেন-গান)" বইটিতে পড়েছি তথ্যের ভিত্তিতে:

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

সুতরাং এখানে আমার প্রথম মিশ্র মাত্রা 8 কেবি পৃষ্ঠা রয়েছে, এটি 76 76৮০ বাইট দিয়ে পপুলেটেড হয়েছে (আমি 30 বার 256 বাইট সাইজের সারিটি sertedোকিয়েছি, তাই 30 * 256 = 7680), আমার রান আকারের চেক প্র্যাকটি যাচাই করা আছে তা পরীক্ষা করতে - এটি নিম্নলিখিত ফলাফলটি প্রদান করে

index_type_desc: CLUSTERED INDEX
index_depth: 1
index_level: 0 
page_count: 1 
record_count: 30 
avg_page_space_used_in_percent: 98.1961947121324
name : TestStructure        
rows : 30   
reserved :  16 KB
data : 8 KB 
index_size : 8 KB       
unused :    0 KB

সুতরাং 16 কেবিটি টেবিলের জন্য সংরক্ষিত আছে, প্রথম 8 কেবি পৃষ্ঠাটি রুট আইএএম পৃষ্ঠার জন্য, দ্বিতীয়টি হ'ল পাতাগুলির ডেটা স্টোরেজ পৃষ্ঠার জন্য যা 8KB occupation 7.5 কেবি অধিকৃত রয়েছে, এখন যখন আমি 256 বাইট সহ একটি নতুন সারি sertোকি:

INSERT INTO dbo.TestStructure (id, filler1, filler2)
VALUES (1, 'a', 'b');

এটি একই পৃষ্ঠায় সঞ্চিত নয় যদিও এটির 256 বাইট (7680 বি + 256 = 7936 যা এখনও 8KB এর চেয়ে কম ছোট) রয়েছে, একটি নতুন ডেটা পৃষ্ঠা তৈরি করা হয়েছে, তবে সেই নতুন সারিটি একই পুরানো পৃষ্ঠায় ফিট হতে পারে কেন, এসকিউএল সার্ভার যখন নতুন স্থান তৈরি করে যখন এটি স্থান সংরক্ষণ করতে পারে এবং অনুসন্ধানের সময়টি বিদ্যমান পৃষ্ঠায় এটি সন্নিবেশ করিয়ে কেনে?

দ্রষ্টব্য: হিপ সূচীতে একই জিনিস ঘটছে।

উত্তর:


9

আপনার ডেটা সারিগুলি 256 বাইট নয়। প্রত্যেকটিই আরও 263 বাইটের মতো। বিশুদ্ধরূপে স্থির দৈর্ঘ্যের ডেটা সারিটির এসকিউএল সার্ভারে ডেটা সারি গঠনের কারণে অতিরিক্ত ওভারহেড থাকে। এই সাইটটি একবার দেখুন এবং কীভাবে ডেটা সারি তৈরি হয় সে সম্পর্কে পড়ুন। http://aboutsqlserver.com/2013/10/15/sql-server-storage-engine-data-pages-and-data-rows/

সুতরাং আপনার উদাহরণে, আপনার একটি ডেটা সারিতে 256 বাইট রয়েছে, স্ট্যাটাস বিটের জন্য 2 বাইট, কলামের সংখ্যার জন্য 2 বাইট, ডেটার দৈর্ঘ্যের জন্য 2 বাইট এবং নাল বিটম্যাপের জন্য অন্য 1 বা আরও যুক্ত করুন। এটি 263 * 30 = 7,890 বাইট। অন্য 263 যোগ করুন এবং আপনি 8kb পৃষ্ঠার সীমা অতিক্রম করেছেন যা অন্য পৃষ্ঠা তৈরি করতে বাধ্য করবে।


আপনি যে লিঙ্কটি সরবরাহ করেছিলেন সেগুলি পৃষ্ঠার কাঠামোর আরও ভাল দৃষ্টি দিতে আমাকে সহায়তা করেছিল, আমি এর অনুরূপ কিছু সন্ধান করছিলাম কিন্তু এটি খুঁজে
পাচ্ছিলাম

11

যদিও এটি সত্য যে এসকিউএল সার্ভারে 1 বা ততোধিক সারি সঞ্চয় করতে 8k (8192 বাইট) ডেটা পৃষ্ঠা ব্যবহার করা হয়, প্রতিটি ডেটা পৃষ্ঠায় কিছু ওভারহেড (96 বাইট) থাকে এবং প্রতিটি সারিতে কিছুটা ওভারহেড থাকে (কমপক্ষে 9 বাইট)। 8192 বাইট খাঁটি ডেটা নয়।

এটি কীভাবে কাজ করে তার আরও বিশদ পরীক্ষার জন্য, দয়া করে নীচের ডিবিএ.এসই প্রশ্নের আমার উত্তরটি দেখুন:

Sys.allocation_units থেকে টেবিলের আকারের সাথে মেলে না এমন DATALENGTH এর SUM

সেই লিঙ্কযুক্ত উত্তরের তথ্য ব্যবহার করে আমরা আসল সারি আকারের একটি পরিষ্কার ছবি পেতে পারি:

  1. সারি শিরোনাম = 4 বাইট
  2. কলামের সংখ্যা = 2 বাইট
  3. নুল বিটম্যাপ = 1 বাইট
  4. সংস্করণ তথ্য ** = 14 বাইট (alচ্ছিক, পাদটীকা দেখুন)
  5. মোট প্রতি সারি ওভারহেড (স্লট অ্যারে বাদে) = সর্বনিম্ন 7 বাইট, বা 21 বাইট সংস্করণ তথ্য উপস্থিত থাকলে
  6. মোট আসল সারি আকার = 263 সর্বনিম্ন (256 ডেটা + 7 ওভারহেড), বা সংস্করণ তথ্য উপস্থিত থাকলে 277 বাইট (256 ডেটা + 21 ওভারহেড)
  7. স্লট অ্যারে যুক্ত করে, সারি প্রতি নেওয়া মোট স্থানটি আসলে হয় 265 বাইট (সংস্করণ তথ্য ছাড়া) বা 279 বাইট (সংস্করণ তথ্য সহ)।

ব্যবহার DBCC PAGEকরে: Record Size 263(for tempdb), এবং Record Size 277(সেট করা একটি ডাটাবেসের জন্য ) দেখিয়ে আমার গণনা নিশ্চিত করে ALLOW_SNAPSHOT_ISOLATION ON

এখন, 30 টি সারি সহ, এটি হল:

  • সংস্করণ তথ্য ছাড়া

    30 * 263 আমাদের 7890 বাইট দেবে। তারপরে 86৯8686 বাইট ব্যবহৃত পৃষ্ঠার পৃষ্ঠা শিরোনামের 96 বাইটে যুক্ত করুন। পরিশেষে, পৃষ্ঠায় ব্যবহৃত মোট 8046 বাইটের জন্য স্লট অ্যারের 60 বাইট (প্রতি সারি 2 টি) যোগ করুন এবং 146 টি বাকী। ব্যবহার DBCC PAGEদেখিয়ে আমার গণনা নিশ্চিত করে :

    • m_slotCnt 30 (অর্থাত্ সারি সংখ্যা)
    • m_freeCnt 146 (অর্থাত্ পৃষ্ঠাতে থাকা বাইট সংখ্যা)
    • m_freeData 7986 (অর্থাত্ ডেটা + পৃষ্ঠা শিরোনাম - 7890 + 96 - স্লট অ্যারে "ব্যবহৃত" বাইট গণনাতে ফ্যাক্টর হয় না)
  • সংস্করণ তথ্য সহ

    মোট 8310 বাইটের জন্য 30 * 277 বাইট। তবে 8310 8192 এরও বেশি, এবং এটি 96 বাইট পৃষ্ঠার শিরোনাম বা সারি স্লট অ্যারে (30 * 2 = 60 বাইট) প্রতি 2 বাইট হিসাবেও সীমাবদ্ধ নয় যা আমাদের সারিগুলির জন্য কেবল 8036 ব্যবহারযোগ্য বাইট দেয়।

    কিন্তু, 29 সারি সম্পর্কে কি? এটি আমাদের পৃষ্ঠার শিরোনামের জন্য 8033 বাইট ডেটা (29 * 277) + 96 বাইট দেবে + স্লট অ্যারের জন্য 58 বাইট (29 * 2) 8187 বাইট সমান। এবং এটি পৃষ্ঠাটি 5 টি বাইট বাকী রেখে যাবে (8192 - 8187; অব্যবহৃত, অবশ্যই)। ব্যবহার DBCC PAGEদেখিয়ে আমার গণনা নিশ্চিত করে :

    • m_slotCnt 29 (অর্থাত্ সারি সংখ্যা)
    • m_freeCnt 5 (অর্থাত্ পৃষ্ঠাতে থাকা বাইট সংখ্যা)
    • m_freeData 8129 (যেমন ডেটা + পৃষ্ঠার শিরোনাম - 8033 + 96 - স্লট অ্যারেটি "ব্যবহৃত" বাইট গণনাতে ফ্যাক্টর করা হয় না)

গাদা সম্পর্কে

স্তূপগুলি ডেটা পৃষ্ঠাগুলি কিছুটা পৃথকভাবে পূরণ করে। তারা পৃষ্ঠায় যে পরিমাণ জায়গার পরিমাণ রেখেছেন তার একটি মোটামুটি অনুমান বজায় রাখে। যখন DBCC আউটপুট দিকে তাকিয়ে, জন্য সারি তাকান: PAGE HEADER: Allocation Status PFS (1:1)। আপনি (যখন আমি ক্লাস্টার্ড টেবিলের দিকে তাকালাম) VALUEলাইনগুলি বরাবর 0x60 MIXED_EXT ALLOCATED 0_PCT_FULLবা 0x64 MIXED_EXT ALLOCATED 100_PCT_FULLহিপ টেবিলটির দিকে তাকানোর কিছু দেখবেন showing এটি প্রতি লেনদেনের জন্য মূল্যায়ন করা হয়, সুতরাং এখানে টেস্টের মতো পৃথক সন্নিবেশ করানো ক্লাস্টার্ড এবং হিপ টেবিলের মধ্যে বিভিন্ন ফলাফল দেখাতে পারে। সমস্ত 30 টি সারির জন্য একটি একক ডিএমএল অপারেশন করা তবে প্রত্যাশারূপে গাদা পূরণ করবে।

তবে, টেবিলের উভয় সংস্করণ কেবলমাত্র 146 বাইট বাকি রেখে 30 টি সারি ফিট করে হ্যাপ সম্পর্কিত এই বিবরণগুলির কোনওটিই সরাসরি এই নির্দিষ্ট পরীক্ষার উপর প্রভাব ফেলবে না। ক্লাস্টার্ড বা হিপ নির্বিশেষে এটি অন্য সারির জন্য পর্যাপ্ত জায়গা নয়।

দয়া করে মনে রাখবেন যে এই পরীক্ষাটি বরং সহজ। একটি সারির প্রকৃত আকার গণনা করা বিভিন্ন কারণের উপর নির্ভর করে খুব জটিল হয়ে SPARSEউঠতে পারে, যেমন :, ডেটা সংক্ষেপণ, এলওবি ডেটা ইত্যাদি etc.


ডেটা পৃষ্ঠার বিশদটি দেখতে, নিম্নলিখিত কোয়েরিটি ব্যবহার করুন:

DECLARE @PageID INT,
        @FileID INT,
        @DatabaseID SMALLINT = DB_ID();

SELECT  @FileID = alloc.[allocated_page_file_id],
        @PageID = alloc.[allocated_page_page_id]
FROM    sys.dm_db_database_page_allocations(@DatabaseID,
                            OBJECT_ID(N'dbo.TestStructure'), 1, NULL, 'DETAILED') alloc
WHERE   alloc.[previous_page_page_id] IS NULL -- first data page
AND     alloc.[page_type] = 1; -- DATA_PAGE

DBCC PAGE(@DatabaseID, @FileID, @PageID, 3) WITH TABLERESULTS;

** 14-বাইট "সংস্করণ তথ্য" মান উপস্থিত হবে যদি আপনার ডাটাবেসটি সেট হয় ALLOW_SNAPSHOT_ISOLATION ONবা হয় READ_COMMITTED_SNAPSHOT ON


সুনির্দিষ্ট হওয়ার জন্য, ব্যবহারকারী প্রতি ডেটা জন্য 8060 বাইট উপলব্ধ। ওপির ডেটা এখনও তার নিচে।
রজার ওল্ফ

সংস্করণ তথ্য নেই, অন্যথায় 30 টি সারি 8310 বাইট নিতে পারে। বাকিগুলি সঠিক বলে মনে হচ্ছে।
রজার ওল্ফ

@ রজারওয়ালফ হ্যাঁ, "সংস্করণ তথ্য" আছে। এবং তাই হ্যাঁ, 30 টি সারিতে 8310 বাইট দরকার। এই কারণেই এই 30 টি সারিটি 1 পৃষ্ঠায় পুরোপুরি মাপসই হয় নি, কারণ ওপি যে কোনও পরীক্ষার জন্য যা ব্যবহার করে তা বিশ্বাস করে। তবে সেই পরীক্ষার অভ্যাসটি ভুল। পৃষ্ঠাটিতে কেবল 29 টি সারি ফিট রয়েছে। আমি এটি নিশ্চিত করেছি (এসকিউএল সার্ভার 2012 এমনকি ব্যবহার করে)।
সলোমন রুটজকি

আপনি কি এমন কোনও ডাটাবেসে পরীক্ষা চালানোর চেষ্টা করেছেন যা আরসিএসআই-সক্ষম নয় / tempdb? আমি ওপি কর্তৃক প্রদত্ত সঠিক সংখ্যা পুনরুত্পাদন করতে সক্ষম হয়েছি।
রজার ওল্ফ

@ রজারওয়াল্ফ আমি যে ডিবিটি ব্যবহার করছি তা আরসিএসআই-সক্ষম নয়, তবে সেট করা আছে ALLOW_SNAPSHOT_ISOLATION। আমি কেবল চেষ্টা করে tempdbদেখেছি যে "সংস্করণ তথ্য" নেই, তাই 30 টি সারি ফিট হয়। আমি নতুন তথ্য যুক্ত করতে আপডেট করব।
সলোমন রুটজকি

3

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

তবে, আপনি লক্ষ্য করেছেন যে এসকিউএল সার্ভার আসলে আপনাকে একটি ইঙ্গিত দেয় যে 31 সারিটি পৃষ্ঠায় ফিট করবে না। পরের সারিতে একই পৃষ্ঠায় ফিট করার জন্য avg_page_space_used_in_percentমানটি 100% - (100/31) = 96.774194 এর নীচে হওয়া উচিত এবং আপনার ক্ষেত্রে এটি এর চেয়েও উপরে।

পিএস আমি বিশ্বাস করি ক্যালেন ডেলানির একটি "এসকিউএল সার্ভার ইন্টার্নাল" বইয়ের ডেটা পৃষ্ঠার কাঠামোর বাইট ব্যাখ্যার জন্য আমি একটি বিশদ দেখতে পেয়েছি, তবে এটি প্রায় 10 বছর আগে ছিল তাই দয়া করে আর কোনও বিবরণ মনে না করার জন্য আমাকে ক্ষমা করে দিন। তদতিরিক্ত, পৃষ্ঠা কাঠামো সংস্করণ থেকে সংস্করণে পরিবর্তিত হয়।


1
না। ইউনিফিফায়ারটি কেবল সারিগুলির সদৃশ করার জন্য যুক্ত করা হয়েছে। প্রতিটি অনন্য কী মানটির প্রথম সারিটিতে অতিরিক্ত 4 বাইট ইউক্লিফায়ার অন্তর্ভুক্ত থাকে না।
সলোমন রুটজকি

@ শ্রুতজকি, আপাতদৃষ্টিতে আপনি ঠিক বলেছেন। কখনই ভাবেন নি যে এসকিউএল সার্ভারটি চলক প্রস্থের কীগুলিকে অনুমতি দেবে। এটি কুৎসিত। দক্ষ, হ্যাঁ, তবে কুরুচিপূর্ণ।
রজার ওল্ফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.