امروز می خوام در مورد یکی از قابلیتهای جالب و کاربردی sql server براتون مطلب بذارم در شرکت ما یه جدول داریم که حجمش شش ترا بایت هست و دیتای روزانه یکی از بانکها رو براساس سرفصل های حسابداری و شعبه های بانک و یه سری چیزای دیگه به صورت روزانه نگه میداره مشکلی که داشتیم این بود که دیتای پایه ممکنه تغییر کنه و کاربر مجبوره برای اون روزی که دیتاش تغییر کرده تایید مالی بزنه در تایید مالی ما دو اتفاق می افتهاولیش محاسبه دیتای اون روز به اضای شعب و سرفصل و ... دوم حذف دیتای قبلی اون دوره از جدول اصلی و انتقال دیتای محاسبه شده جدید این اتفاق برای هر روز بیش از 35 دقیقه طول می کشید که فقط حذف اون دوره 15 دقیقه طول می کشید به دلیل حجم زیاد دیتا من این تایید مالی به زیر ده دقیقه رسوندم با کمک همین پارتیشن بندی جدول، چطور ؟ به ازای هر دوره که داشتیم یه پارتیشن درست کردم و دیتای اون دوره داخل پارتیشن خودش گذاشتم باور نکردنی هست هم عملیات درج و هم عملیات حذف اون دوره نزدیک به صفر ثانیه اتفاق می افتاد و این کمک بزرگی به ما کرد در ادمه کدهاش می ذارم امیدوارم این مطلب به درد تون بخوره
من اول کد ساخت پارتیشن میذارم بعد توضیح میدم
CREATE PARTITION FUNCTION نام پارتیشن فانکشن (SMALLINT)
AS
RANGE LEFT FOR VALUES (مقدار اولین پارتیشن)
GO
CREATE PARTITION SCHEME نام شِما پارتیشن
AS
PARTITION نام پارتیشن فانکشنALL TO([اسم فایل گروپ جدول])
GO
CREATE PARTITION SCHEME نام شِما پارتیشن ایندکس
AS
PARTITION نام پارتیشن فانکشنALL TO([اسم فایل گروپ ایندکس])
GO
اول از همه ما باید یک Partition Function درست کنیم که تنظیمات اولیه پارتیشن ما رو شامل میشه کد اسکریپتش می تونید در خط اول مشاهده کنید داخل پرانتز نوع ستونی که می خوایم براساس اون پارتیشن بندی کنیم می ذاریم من اینجا چون دوره هام توی یه جدول دیگه ذخیره کردم و مقدار id اون در جدول دیتا نگه میدارم پس نوع ستونم SMALLINT هست حال برای شما ممکنه هر چیز دیگه ای باشه
در خط بعد میشه لیست پارتیشن ها بهش داد من فعلا دو تا رو بهش دادم وبعدا میشه به این پارتیشن ها اضافه کرد.
گام بعدی پس از ایجاد Partition Function، تعریف Partition Schema است، که به منظور قرار گرفتن هر یک از پارتیشنهای تعریف شده توسط Function در Filegroupهای مناسب آن استفاده میشود و من در اینجا دو تا Schema ساختم یکی برای دیتا یکی هم برای ایندکس ها حالا نوبت ساخت جداول مربوطه ست من دو تا جدول داشتم که یکی temp بود و مقادیر محاسبه شده نگه میداشت و یکی هم جدول اصلی که بعد از محاسبه دیتای temp به اون انتقال میدادم برای ساخت جدولی که پارتیشن بندی شده باشه کافیه ته اسکریپت ساخت جدول خط زیر اضافه کنیم
Create Table <name> (…)
ON partitionShemaName (نام ستونی که می خواهیم روی اون پارتیشن کنیم)
همچنین این کار برای ساخت ایندکس جدول هم انجام می دهیم
Create
NONCLUSTERED INDEX<name> (…)
ON partitionShemaIndex (نام ستونی که می خواهیم روی اون پارتیشن کنیم)
جداول ما آماده ست
خوب حالا میریم سراغ استفاده از این پارتیشن بندی
من یه اسکریپت نوشتم که اول چک می کنیم توی پارتیشن مورد نظرمون دوره ای که می خوایم براش دیتا بزنیم وجود داره یا نه اگه وجود نداشت اون دوره به پارتیشن های قبلی اضافه می کنیم با اینکار دیگه نیازی نیست موقع ساخت پارتیشن حتما همه پارتیشن ها اضافه کنیم، در گام بعد سراغ استفاده از این پارتیشن بندی میریم
--حذف اطلاعات جدول اصلی برای این دوره
TRUNCATE TABLE [dbo].[اسم جدول تون] WITH (PARTITIONS ($PARTITION.نام پارتیشن فانکشن(@IntervalId)));
--انتقال اطلاعات این دوره از تمپ به جدول اصلی
ALTER TABLE [temp].[اسم جدول تون]
SWITCH PARTITION $PARTITION.نام پارتیشن فانکشن(PartitionValue)
TO [dbo].[اسم جدول تون] PARTITION $PARTITION.نام پارتیشن فانکشن(PartitionValue);
همون طور که توی کد توضیح دادم خط اول تمامی اطلاعات اون دوره از جدول اصلی در کسری از ثانیه حذف می کنه و در قسمت بعدی اطلاعات جدول موقت برای دوره مورد نظر ما به جدول اصلی انتقال میده بدون اینکه زمانی از شما گرفته باشه و جالبه بدونید این انتقال با حذف دیتا از جدول موقت هم همراه هست و دیگه نیازی به خالی کردن جدول موقت نداریم مقدار IntervalId هم شناسه دوره مورد نظرمون برای تایید مالی هست.
در پایان اینو بگم که sql server می تونه تا 15 هزار پارتیشن ساپورت کنه یعنی اگه برای تمام روزهای سال دیتا داشته باشیم تا 41 سال دیتا رو می تونیم به این روش پارتیشن بندی کنیم که این فوق العاده ست جهت اطلاعات بیشتر به لینک Partitioned Tables and Indexes مراجعه کنید.
سلام مرسی از مطلب خوبتون
ادمین : سلام مهندس ممنون از شما که وقت گذاشتید
بسیار عالی. شما بهترین همکار من هستید. برای شما آرزوی موفقیت دارم.
ادمین : قربانِ رئیس