سلام دوستان
🛒 یادتونه سالها قبل از اینکه هایپراستار بیاد، برای هر چیزی مجبور بودیم بریم یه فروشگاه مخصوص همون؟
هیچ مرجعی نبود که یکجا همه نیازها رو پوشش بده.
وقتی هایپراستار اومد، ملت استقبال کردن چون همهچی یه جا جمع بود:
✅ برندهای خوب
✅ اجناس درستحسابی
✅ خرید راحتتر
نتیجه؟ دسترسی سادهتر به کالاها و در عوض فروش مغازههای اطراف به شدت افت کرد.
حالا دقیقاً همین اتفاق توی دنیای SQL Server و Data Warehouse (DW) میفته.
📊 توی DW:
دادهها از منابع مختلف (مثل همون فروشگاهها یا کارخانهها) جمع میشن.
برای رکوردها Master Data پیادهسازی میشه (یه کدینگ واحد برای کالاها).
دادهها تمیز و پاکسازی میشن (کالاهای خراب و برندهای ضعیف حذف میشن).
و در نهایت کاربر با یه منبع دادهی مرتب و درست سروکله میزنه و میتونه به صورت تجمیعی به همه نیازهای گزارشگیری و تصمیمگیری دسترسی داشته باشه—بدون اینکه مجبور باشه بره سراغ تکتک سیستمها.
⚠️ پس اگه جایی اومدن براتون DW و BI راه انداختن ولی این اتفاقا نیفتاد… احتمالاً یه جای کار میلنگه 😉
🛒 یادتونه سالها قبل از اینکه هایپراستار بیاد، برای هر چیزی مجبور بودیم بریم یه فروشگاه مخصوص همون؟
هیچ مرجعی نبود که یکجا همه نیازها رو پوشش بده.
وقتی هایپراستار اومد، ملت استقبال کردن چون همهچی یه جا جمع بود:
✅ برندهای خوب
✅ اجناس درستحسابی
✅ خرید راحتتر
نتیجه؟ دسترسی سادهتر به کالاها و در عوض فروش مغازههای اطراف به شدت افت کرد.
حالا دقیقاً همین اتفاق توی دنیای SQL Server و Data Warehouse (DW) میفته.
📊 توی DW:
دادهها از منابع مختلف (مثل همون فروشگاهها یا کارخانهها) جمع میشن.
برای رکوردها Master Data پیادهسازی میشه (یه کدینگ واحد برای کالاها).
دادهها تمیز و پاکسازی میشن (کالاهای خراب و برندهای ضعیف حذف میشن).
و در نهایت کاربر با یه منبع دادهی مرتب و درست سروکله میزنه و میتونه به صورت تجمیعی به همه نیازهای گزارشگیری و تصمیمگیری دسترسی داشته باشه—بدون اینکه مجبور باشه بره سراغ تکتک سیستمها.
⚠️ پس اگه جایی اومدن براتون DW و BI راه انداختن ولی این اتفاقا نیفتاد… احتمالاً یه جای کار میلنگه 😉
❤6👍1
سلام
🚀 یکی از پروژههای بهینهسازی دیتابیس که این روزا روش کار میکنم، یه ماجرای جالب داشت:
رفیقای قدیم یه علاقه خاصی به ایندکس داشتن 😅
تو جداول پرکاربرد، رو هر چی فیلد بود یه ایندکس ساخته بودن!
بعدش مثلاً علی رفته بود یه ایندکس روی تاریخ گذاشته، محمد اومده دیده "ای بابا! این علی بدون وضو ایندکس روی تاریخ گذاشته. خلاصه با نیت خالص و با وضو دوباره روی تاریخ ایندکس ایجاد کرده شاید امید به خدا درست کار کنه. " 😅✌️
ولی خب اون قبلی رو حذف نکرده بود، فقط اضافه کرده بود!
نامگذاریها هم در حد لیگ قهرمانان اروپا 🤦♂️ از 1 شروع کرده بودن و خیاری ادامه داده بودن.
📞 آخرش هم مشتری زنگ میزنه:
"داداش میخوایم یه رکورد ثبت کنیم، جد و آبادمون داره جلوی چشممون رد میشه! چند دقیقه باید صبر کنیم تا بشه!"
یاد اون دیالوگ اکبر عبدی توی اخراجیها افتادم که میگفت:
«بابام میگفت هرچی نماز بیشتر بخونی بهتره»
اینا هم فکر کردن هرچی ایندکس بیشتر بذارن، دیتابیس خوشحالتر میشه! 😂
گفتن دیگه از ایندکس چیزی برای دیتابیس کم و کسری نذاریم. 😂
🔑 نتیجه اخلاقی:
خداوکیلی این مدلی دیتابیس طراحی نکنید. ایندکسگذاری علمه، نه تعداد! 😉
🚀 یکی از پروژههای بهینهسازی دیتابیس که این روزا روش کار میکنم، یه ماجرای جالب داشت:
رفیقای قدیم یه علاقه خاصی به ایندکس داشتن 😅
تو جداول پرکاربرد، رو هر چی فیلد بود یه ایندکس ساخته بودن!
بعدش مثلاً علی رفته بود یه ایندکس روی تاریخ گذاشته، محمد اومده دیده "ای بابا! این علی بدون وضو ایندکس روی تاریخ گذاشته. خلاصه با نیت خالص و با وضو دوباره روی تاریخ ایندکس ایجاد کرده شاید امید به خدا درست کار کنه. " 😅✌️
ولی خب اون قبلی رو حذف نکرده بود، فقط اضافه کرده بود!
نامگذاریها هم در حد لیگ قهرمانان اروپا 🤦♂️ از 1 شروع کرده بودن و خیاری ادامه داده بودن.
📞 آخرش هم مشتری زنگ میزنه:
"داداش میخوایم یه رکورد ثبت کنیم، جد و آبادمون داره جلوی چشممون رد میشه! چند دقیقه باید صبر کنیم تا بشه!"
یاد اون دیالوگ اکبر عبدی توی اخراجیها افتادم که میگفت:
«بابام میگفت هرچی نماز بیشتر بخونی بهتره»
اینا هم فکر کردن هرچی ایندکس بیشتر بذارن، دیتابیس خوشحالتر میشه! 😂
گفتن دیگه از ایندکس چیزی برای دیتابیس کم و کسری نذاریم. 😂
🔑 نتیجه اخلاقی:
خداوکیلی این مدلی دیتابیس طراحی نکنید. ایندکسگذاری علمه، نه تعداد! 😉
👍21❤6😁6💯1🤣1
سلام
💔 داستان Shrink در SQL Server 😅
ببینید رفقا، این عملیات Shrink کردن فایلهای Data عین روابط عاشقانهی پر فراز و نشیبِیه! 😎
یه روز SQL Server میگه:
"دیگه بهت نیاز ندارم 😤"
و فایل Data رو کوچیک میکنه (کات میکنن خلاصه 💔)
بعد صبح روز بعد دوباره میاد:
"ببین من یه چیزی گفتم... 😅 بیا دوباره با هم باشیم!"
و دوباره فضا میگیره 😬
شب دوباره job shrink اجرا میشه 😑
صبح دوباره SQL Server میاد میگه «برگرد پیشم!»
و این چرخه تا ابد ادامه داره... 😭
📣 بابا ولش کنین دیگه! Shrink نکنید، بذارید رابطهش آروم بگیره 😂
#SQLServer #DBA #ShrinkDrama #DatabaseHumor #ITLife #DBALife
💔 داستان Shrink در SQL Server 😅
ببینید رفقا، این عملیات Shrink کردن فایلهای Data عین روابط عاشقانهی پر فراز و نشیبِیه! 😎
یه روز SQL Server میگه:
"دیگه بهت نیاز ندارم 😤"
و فایل Data رو کوچیک میکنه (کات میکنن خلاصه 💔)
بعد صبح روز بعد دوباره میاد:
"ببین من یه چیزی گفتم... 😅 بیا دوباره با هم باشیم!"
و دوباره فضا میگیره 😬
شب دوباره job shrink اجرا میشه 😑
صبح دوباره SQL Server میاد میگه «برگرد پیشم!»
و این چرخه تا ابد ادامه داره... 😭
📣 بابا ولش کنین دیگه! Shrink نکنید، بذارید رابطهش آروم بگیره 😂
#SQLServer #DBA #ShrinkDrama #DatabaseHumor #ITLife #DBALife
😁13🤣9❤8👍6
سلام عزیزان
امیدوارم عالی باشین
از این لینک میتونید SQL Server 2025 Developer Edition رو دانلود کنید و باهاش کار کنید و لذت ببرید
فقط سرجدتون از فردا همه پروژه هارو نبرید روی 2025. بذارید حداقل 1 سال از عرضه اون بگذره بعد سوئیچ کنید.😁
شاد باشین
حمیدرضا صادقیان
https://www.microsoft.com/en-us/sql-server/sql-server-downloads
امیدوارم عالی باشین
از این لینک میتونید SQL Server 2025 Developer Edition رو دانلود کنید و باهاش کار کنید و لذت ببرید
فقط سرجدتون از فردا همه پروژه هارو نبرید روی 2025. بذارید حداقل 1 سال از عرضه اون بگذره بعد سوئیچ کنید.😁
شاد باشین
حمیدرضا صادقیان
https://www.microsoft.com/en-us/sql-server/sql-server-downloads
Microsoft
SQL Server Downloads | Microsoft
Get started with Microsoft SQL Server downloads. Choose a SQL Server trial, edition, tool, or connector that best meets your data and workload needs.
👌13😁8❤6
سلام دوستان
🔄 همانطور که قول داده بودم، امروز میخواهم درباره فرآیند انتقال اطلاعات (Data Migration) که پیشتر دربارهاش نوشته بودم، توضیح بدم.
برای انجام یک مهاجرت دادهای تمیز، قابل اعتماد و بدون دردسر، چند مرحله کلیدی را طی کردم:
🖥 1. راهاندازی محیط محلی
اول از همه یک سیستم محلی روی لپتاپم راهاندازی کردم تا بتوانم دیتابیس را کامل و دقیق بررسی کنم.
ساختار جداول، فیلدهای حساس، ارتباطات و ساختارهای درختی را تحلیل کردم تا بدانم هر تغییر چه تبعاتی دارد.
🗂 2. آمادهسازی دیتابیس مقصد
دیتابیسهای مقصد را روی سیستمم بالا آوردم و شروع کردم به نوشتن اسکریپت جداول اصلی.
اینجا نکته مهم این است که ترتیب ساخت جداول را دقیق رعایت کنید؛
چون برخی جداول، دادههای پایهای دارند و اگر ترتیب اشتباه باشد، با چالشهای جدی مواجه میشوید.
🔁 3. ایجاد جدول Duplicate برای مدیریت دادههای تکراری
برای هر جدول، یک جدول جدید به نام Duplicate ساختم.
هر رکوردی که احتمال تکرار ID داشت، وارد این جدول میشد تا بعداً دربارهاش تصمیم بگیرم.
در پروژه فعلی، IDها از نوع GUID هستند، پس احتمال تکرار بسیار کم است — اما وجود این لایه کنترلی ضروری است.
🚚 4. تست انتقال کامل دادهها
ابتدا کدهای تولید داده و انتقال اطلاعات را نوشتم و کل دیتا را جابهجا کردم تا از صحت فرآیند مطمئن شوم.
بعد از تأیید، آن را تبدیل به پکیج کردم تا:
- قابل نگهداریتر باشد،
- برای سایر دیتابیسها هم قابل استفاده باشد،
- و تغییرات در آینده راحتتر اعمال شود.
🛡 5. بکاپگیری قبل از هر مرحله
از دیتابیس خام یک بکاپ کامل گرفتم.
هر زمان فرآیند به مشکل میخورد، بکاپ را ریستور میکردم و دوباره مرحله را تست میکردم.
این کار زمان میگیرد، اما تضمین میکند فرآیند Migration تمیز و مطمئن پیش برود.
✔️ 6. تست نهایی با نرمافزار
در پایان، خروجی را با نرمافزار اصلی تست کردم و خوشبختانه همه چیز درست بود.
📌 در پستهای بعدی، نکات عمیقتر و تجربیات بیشتری را درباره طراحی پکیجهای Migration و چالشهای واقعی پروژهها به اشتراک میگذارم.
شاد باشین.
@Hamidreza_Sadeghian
🔄 همانطور که قول داده بودم، امروز میخواهم درباره فرآیند انتقال اطلاعات (Data Migration) که پیشتر دربارهاش نوشته بودم، توضیح بدم.
برای انجام یک مهاجرت دادهای تمیز، قابل اعتماد و بدون دردسر، چند مرحله کلیدی را طی کردم:
🖥 1. راهاندازی محیط محلی
اول از همه یک سیستم محلی روی لپتاپم راهاندازی کردم تا بتوانم دیتابیس را کامل و دقیق بررسی کنم.
ساختار جداول، فیلدهای حساس، ارتباطات و ساختارهای درختی را تحلیل کردم تا بدانم هر تغییر چه تبعاتی دارد.
🗂 2. آمادهسازی دیتابیس مقصد
دیتابیسهای مقصد را روی سیستمم بالا آوردم و شروع کردم به نوشتن اسکریپت جداول اصلی.
اینجا نکته مهم این است که ترتیب ساخت جداول را دقیق رعایت کنید؛
چون برخی جداول، دادههای پایهای دارند و اگر ترتیب اشتباه باشد، با چالشهای جدی مواجه میشوید.
🔁 3. ایجاد جدول Duplicate برای مدیریت دادههای تکراری
برای هر جدول، یک جدول جدید به نام Duplicate ساختم.
هر رکوردی که احتمال تکرار ID داشت، وارد این جدول میشد تا بعداً دربارهاش تصمیم بگیرم.
در پروژه فعلی، IDها از نوع GUID هستند، پس احتمال تکرار بسیار کم است — اما وجود این لایه کنترلی ضروری است.
🚚 4. تست انتقال کامل دادهها
ابتدا کدهای تولید داده و انتقال اطلاعات را نوشتم و کل دیتا را جابهجا کردم تا از صحت فرآیند مطمئن شوم.
بعد از تأیید، آن را تبدیل به پکیج کردم تا:
- قابل نگهداریتر باشد،
- برای سایر دیتابیسها هم قابل استفاده باشد،
- و تغییرات در آینده راحتتر اعمال شود.
🛡 5. بکاپگیری قبل از هر مرحله
از دیتابیس خام یک بکاپ کامل گرفتم.
هر زمان فرآیند به مشکل میخورد، بکاپ را ریستور میکردم و دوباره مرحله را تست میکردم.
این کار زمان میگیرد، اما تضمین میکند فرآیند Migration تمیز و مطمئن پیش برود.
✔️ 6. تست نهایی با نرمافزار
در پایان، خروجی را با نرمافزار اصلی تست کردم و خوشبختانه همه چیز درست بود.
📌 در پستهای بعدی، نکات عمیقتر و تجربیات بیشتری را درباره طراحی پکیجهای Migration و چالشهای واقعی پروژهها به اشتراک میگذارم.
شاد باشین.
@Hamidreza_Sadeghian
❤16
سلام دوستان عزیز
🔍 SET FMTONLY دقیقاً چیه و چرا دیگه بهتره ازش استفاده نکنیم؟
یه نکته فنی که این چند روز دوباره باهاش برخورد کردم و گفتم اینجا هم بگم:
SET FMTONLY ON
خیلیها هنوز توی پروژهها استفاده میکنن، در حالی که واقعاً دیگه وقتشه بذاریمش کنار 😄
🧪 SET FMTONLY ON یعنی چی؟
وقتی این گزینه رو فعال میکنی:
SET FMTONLY ON;
SELECT * FROM Sales.Orders;
SQL Server اصلاً کوئری رو اجرا نمیکنه!
فقط ساختار خروجی رو میده:
- اسم ستونها
- نوع دادهها
- نه دیتا میخونه
- نه لاجیک اجرا میکنه
- نه Temp Table میسازه
- نه حتی Cross DB Query اجرا میشه!
برای همون دوران ADO و ODBC قدیم ساخته شده بود.
❌ مشکلش چیه؟
FMTONLY از SQL 2012 به بعد رسماً منقرض شده (Deprecated) چون:
- با Temp Table و Table Variable قاطی میکنه
- خیلی وقتها خطای Invalid object name میده
- خروجی DMVها نصفهنیمه برمیگردونه
- روی نسخههای مختلف SQL Server متفاوت رفتار میکنه
دقیقاً همون چیزیه که تو ابزارهای مانیتورینگ یا ORMها باعث Errorهای عجیب میشه.
✔️ جایگزین استاندارد و مدرن
بهجاش از این DMV فوقالعاده استفاده کنید:
SELECT *
FROM sys.dm_exec_describe_first_result_set
(
N'SELECT CustomerId, TotalPrice FROM Sales.Orders',
NULL,
NULL
);
این کارها رو انجام میده:
✔️ کوئری رو اجرا نمیکنه
✔️ ساختار دقیق نتیجه رو برمیگردونه
✔️ با نسخههای مختلف SQL Server سازگاره
✔️ با Temp Table و Dynamic SQL هم درست کار میکنه
🔥 مثال عملیِ واقعی
فرض کن یک Stored Procedure داری:
CREATE PROCEDURE dbo.UspGetOrders
AS
BEGIN
SELECT TOP 100 OrderId, CustomerId, TotalAmount
FROM Sales.Orders
ORDER BY OrderDate DESC;
END
میخوای فقط ساختار خروجی رو ببینی، بدون اینکه SP رو واقعاً اجرا کنی:
SELECT *
FROM sys.dm_exec_describe_first_result_set
(
N'EXEC dbo.UspGetOrders',
NULL,
NULL
);
که میاد ساختار جداول و فیلدها رو بهتون ارائه میده.
شما تاحالا ازش استفاده کردین؟
🔍 SET FMTONLY دقیقاً چیه و چرا دیگه بهتره ازش استفاده نکنیم؟
یه نکته فنی که این چند روز دوباره باهاش برخورد کردم و گفتم اینجا هم بگم:
SET FMTONLY ON
خیلیها هنوز توی پروژهها استفاده میکنن، در حالی که واقعاً دیگه وقتشه بذاریمش کنار 😄
🧪 SET FMTONLY ON یعنی چی؟
وقتی این گزینه رو فعال میکنی:
SET FMTONLY ON;
SELECT * FROM Sales.Orders;
SQL Server اصلاً کوئری رو اجرا نمیکنه!
فقط ساختار خروجی رو میده:
- اسم ستونها
- نوع دادهها
- نه دیتا میخونه
- نه لاجیک اجرا میکنه
- نه Temp Table میسازه
- نه حتی Cross DB Query اجرا میشه!
برای همون دوران ADO و ODBC قدیم ساخته شده بود.
❌ مشکلش چیه؟
FMTONLY از SQL 2012 به بعد رسماً منقرض شده (Deprecated) چون:
- با Temp Table و Table Variable قاطی میکنه
- خیلی وقتها خطای Invalid object name میده
- خروجی DMVها نصفهنیمه برمیگردونه
- روی نسخههای مختلف SQL Server متفاوت رفتار میکنه
دقیقاً همون چیزیه که تو ابزارهای مانیتورینگ یا ORMها باعث Errorهای عجیب میشه.
✔️ جایگزین استاندارد و مدرن
بهجاش از این DMV فوقالعاده استفاده کنید:
SELECT *
FROM sys.dm_exec_describe_first_result_set
(
N'SELECT CustomerId, TotalPrice FROM Sales.Orders',
NULL,
NULL
);
این کارها رو انجام میده:
✔️ کوئری رو اجرا نمیکنه
✔️ ساختار دقیق نتیجه رو برمیگردونه
✔️ با نسخههای مختلف SQL Server سازگاره
✔️ با Temp Table و Dynamic SQL هم درست کار میکنه
🔥 مثال عملیِ واقعی
فرض کن یک Stored Procedure داری:
CREATE PROCEDURE dbo.UspGetOrders
AS
BEGIN
SELECT TOP 100 OrderId, CustomerId, TotalAmount
FROM Sales.Orders
ORDER BY OrderDate DESC;
END
میخوای فقط ساختار خروجی رو ببینی، بدون اینکه SP رو واقعاً اجرا کنی:
SELECT *
FROM sys.dm_exec_describe_first_result_set
(
N'EXEC dbo.UspGetOrders',
NULL,
NULL
);
که میاد ساختار جداول و فیلدها رو بهتون ارائه میده.
شما تاحالا ازش استفاده کردین؟
👏10❤5👍2👌2
گاهی وقتا برای فهمیدن پشتصحنهی واقعی SQL Server باید یه ذره چراغقوهی مخفی روشن کنیم 😎🔦
یکی از چیزهایی که همیشه کمکم کرده بفهمم دقیقاً اون زیر چه خبره، همین دستور معروفه:
dbcc traceon(3004,3604,-1)
این دستور باعث میشه جزییات کامل عملیات Backup و Restore رو ببینی؛
جزییاتی که SQL Server معمولاً ساکت و بیصدا انجامشون میده ولی ما میخوایم بدونیم دقیقاً در حال رخ دادن چیه ⚙️👀
نکتهی جالبش اینه که تو این جزییات دقیقاً مشخص میکنه:
✔️بکاپ یا ریستور با چه پارامترهایی داره انجام میشه،
✔️کدوم مرحله بیشترین زمان رو میبلعه،
✔️و چطور میتونی کل فرآیند رو بهینهتر کنی ⏱️🚀
وقتی فعالش میکنی، انگار وارد اتاق کنترل موتور SQL Server شدی و داری قدمبهقدم همهچیز رو لایو نگاه میکنی 🔍💡
و اما نکتهی مهم برای کسایی که تازه با این Trace Flagها آشنا میشن:
✔️Trace Flag 3004: مسئول نوشتن لاگ عملیات Backup/Restore هست.
✔️Trace Flag 3604: به SQL Server میگه همین لاگها رو مستقیم داخل نتیجهی همون کوئری نشون بده.
یعنی دقیقاً همان لحظه همونجا میبینی چه اتفاقی داره میفته 😍📜
برای من این چیزا فقط یه دستور نیستن؛
کلیدهایی هستن برای اینکه رفتار دیتابیس رو بفهمم، تحلیل کنم و دقیقتر از همیشه بهینهسازی انجام بدم.
#SQLServer #DBA #TraceFlag #BackupRestore #PerformanceTuning #DatabaseInternals #Monitoring #MicrosoftSQLServer #DataEngineering
یکی از چیزهایی که همیشه کمکم کرده بفهمم دقیقاً اون زیر چه خبره، همین دستور معروفه:
dbcc traceon(3004,3604,-1)
این دستور باعث میشه جزییات کامل عملیات Backup و Restore رو ببینی؛
جزییاتی که SQL Server معمولاً ساکت و بیصدا انجامشون میده ولی ما میخوایم بدونیم دقیقاً در حال رخ دادن چیه ⚙️👀
نکتهی جالبش اینه که تو این جزییات دقیقاً مشخص میکنه:
✔️بکاپ یا ریستور با چه پارامترهایی داره انجام میشه،
✔️کدوم مرحله بیشترین زمان رو میبلعه،
✔️و چطور میتونی کل فرآیند رو بهینهتر کنی ⏱️🚀
وقتی فعالش میکنی، انگار وارد اتاق کنترل موتور SQL Server شدی و داری قدمبهقدم همهچیز رو لایو نگاه میکنی 🔍💡
و اما نکتهی مهم برای کسایی که تازه با این Trace Flagها آشنا میشن:
✔️Trace Flag 3004: مسئول نوشتن لاگ عملیات Backup/Restore هست.
✔️Trace Flag 3604: به SQL Server میگه همین لاگها رو مستقیم داخل نتیجهی همون کوئری نشون بده.
یعنی دقیقاً همان لحظه همونجا میبینی چه اتفاقی داره میفته 😍📜
برای من این چیزا فقط یه دستور نیستن؛
کلیدهایی هستن برای اینکه رفتار دیتابیس رو بفهمم، تحلیل کنم و دقیقتر از همیشه بهینهسازی انجام بدم.
#SQLServer #DBA #TraceFlag #BackupRestore #PerformanceTuning #DatabaseInternals #Monitoring #MicrosoftSQLServer #DataEngineering
👏15❤6👌2👍1
امروز برای بررسی یک دیتابیس از یک نرمافزار در کشور دوست و همسایه 🌍 (همون سرزمین فرصتها و محل تحقق آمال و آرزوهای همه ما 😅✈️) وصل شدم.
حالا اینکه مدیریت درستوحسابی دیتابیس نداشتن، بماند… 🤦♂️
اما اصل ماجرا 👇
رفتم سراغ Jobهای بکاپ.
دیدم دوست عزیزمون رفته پنل زمانبندی رو باز کرده،
چون برای هر روز هفته یه چکباکس گذاشته بودن،
ایشون هم فکر کرده باید برای هر روز یه Job جدید بسازه! 😂😂
یعنی ۷ تا جاب بکاپ، یکی برای شنبه، یکی دوشنبه…
انگار بکاپ گرفتن نذریه و باید روز به روز پخش بشه 😄🍛
بابا یه دونه ماوس برداری یه دابلکلیک بزنی ببینی شاید بشه چندتا روز رو با هم انتخاب کرد…
ولی خب… ظاهراً ماوسش همون روز مرخصی بوده 🐭💤
راستش چیزهای عجیب زیاد دیدم،
اما این یکی واقعاً هنر خاصی میخواست 🎨😆
شما تا حالا به همچین شاهکارهای مهندسی برخوردین؟
تجربههای باحال و عجیبغریبتون رو بگین بخندیم 😂👇
حالا اینکه مدیریت درستوحسابی دیتابیس نداشتن، بماند… 🤦♂️
اما اصل ماجرا 👇
رفتم سراغ Jobهای بکاپ.
دیدم دوست عزیزمون رفته پنل زمانبندی رو باز کرده،
چون برای هر روز هفته یه چکباکس گذاشته بودن،
ایشون هم فکر کرده باید برای هر روز یه Job جدید بسازه! 😂😂
یعنی ۷ تا جاب بکاپ، یکی برای شنبه، یکی دوشنبه…
انگار بکاپ گرفتن نذریه و باید روز به روز پخش بشه 😄🍛
بابا یه دونه ماوس برداری یه دابلکلیک بزنی ببینی شاید بشه چندتا روز رو با هم انتخاب کرد…
ولی خب… ظاهراً ماوسش همون روز مرخصی بوده 🐭💤
راستش چیزهای عجیب زیاد دیدم،
اما این یکی واقعاً هنر خاصی میخواست 🎨😆
شما تا حالا به همچین شاهکارهای مهندسی برخوردین؟
تجربههای باحال و عجیبغریبتون رو بگین بخندیم 😂👇
😁14🔥5👍3
سلام دوستان.
🔧 بهینهسازی حذف 17 میلیون رکورد در SQL Server 🚀
قرار بود از یک جدول، حدود 17 میلیون رکورد حذف بشه.
منطق اولیه به این صورت بود که:
🔹 داخل یک حلقه، با یک SELECT
🔹 هر بار 20,000 رکورد در یک Local Variable ریخته میشد
🔹 و سپس عملیات حذف انجام میگرفت
⏳ این روش بهشدت کند بود و فرآیند حذف چندین ساعت زمان میبرد.
💡 راهکاری که پیادهسازی کردم:
✅ منطق را بهطور کامل بازطراحی کردم:
1️⃣ دستور SELECT را از داخل حلقه خارج کردم
2️⃣ یک Temporary Table ساختم
3️⃣ تمام IDهای موردنظر را یکجا داخل آن INSERT کردم
4️⃣ روی جدول Temp یک Index مناسب ایجاد کردم ⚡️
5️⃣ در حلقه، هر بار فقط 20,000 رکورد:
از جداول اصلی حذف میشد و همان 20,000 رکورد از جدول Temp هم پاک میشد
🔁 کل فرآیند در قالب یک Transaction کنترلشده انجام شد
📌 بهطوری که بعد از هر 20,000 رکورد COMMIT میشد تا:
رشد Transaction Log کنترل بشه.
با توجه به Auto Backupهای مداوم، فایل لاگ من رشد نمیکرد که باعث ترکیدن سیستم بشه.
🎯 نتیجه نهایی:
🔥 حذف کامل 17,000,000 رکورد فقط در 56 دقیقه
📉 کاهش چشمگیر زمان اجرا
📉 کنترل مصرف لاگ
📈 افزایش پایداری سیستم در زمان عملیات
⚠️ نکته مهم درباره علت کندی اولیه:
روی جدول، Cascade Delete فعال بود
و به دلیل محدودیتهای سیستمی امکان تغییر آن وجود نداشت
بنابراین بهینهسازی باید کاملاً در سطح منطق اجرا و معماری حذف داده انجام میشد، نه ساختار دیتابیس.
🔧 بهینهسازی حذف 17 میلیون رکورد در SQL Server 🚀
قرار بود از یک جدول، حدود 17 میلیون رکورد حذف بشه.
منطق اولیه به این صورت بود که:
🔹 داخل یک حلقه، با یک SELECT
🔹 هر بار 20,000 رکورد در یک Local Variable ریخته میشد
🔹 و سپس عملیات حذف انجام میگرفت
⏳ این روش بهشدت کند بود و فرآیند حذف چندین ساعت زمان میبرد.
💡 راهکاری که پیادهسازی کردم:
✅ منطق را بهطور کامل بازطراحی کردم:
1️⃣ دستور SELECT را از داخل حلقه خارج کردم
2️⃣ یک Temporary Table ساختم
3️⃣ تمام IDهای موردنظر را یکجا داخل آن INSERT کردم
4️⃣ روی جدول Temp یک Index مناسب ایجاد کردم ⚡️
5️⃣ در حلقه، هر بار فقط 20,000 رکورد:
از جداول اصلی حذف میشد و همان 20,000 رکورد از جدول Temp هم پاک میشد
🔁 کل فرآیند در قالب یک Transaction کنترلشده انجام شد
📌 بهطوری که بعد از هر 20,000 رکورد COMMIT میشد تا:
رشد Transaction Log کنترل بشه.
با توجه به Auto Backupهای مداوم، فایل لاگ من رشد نمیکرد که باعث ترکیدن سیستم بشه.
🎯 نتیجه نهایی:
🔥 حذف کامل 17,000,000 رکورد فقط در 56 دقیقه
📉 کاهش چشمگیر زمان اجرا
📉 کنترل مصرف لاگ
📈 افزایش پایداری سیستم در زمان عملیات
⚠️ نکته مهم درباره علت کندی اولیه:
روی جدول، Cascade Delete فعال بود
و به دلیل محدودیتهای سیستمی امکان تغییر آن وجود نداشت
بنابراین بهینهسازی باید کاملاً در سطح منطق اجرا و معماری حذف داده انجام میشد، نه ساختار دیتابیس.
👍23🔥8❤5🙏2🤷♂1
سلام دوستان
🔍 یک چالش جالب در SQL Server که میتونست یک مجموعه رو زمینگیر کنه!
چند وقت پیش در یکی از مجموعهها با یک مشکل عجیب مواجه بودن 👀
سیستم از یک تعداد کاربر مشخص به بعد خطا میداد و اجازه نمیداد اتصال جدیدی به دیتابیس برقرار بشه.
🔎 بعد از دیدن خطا، اولین چیزی که به ذهنم رسید این بود:
احتمالاً تنظیمات user connections دستکاری شده.
مشکل اینجا بود که حتی اتصال عادی هم به دیتابیس برقرار نمیشد!
با کلی داستان و از طریق sqlcmd تونستم مستقیم به Engine وصل بشم 💪
📌 با بررسی تنظیمات:
'sp_configure 'user connections
مشخص شد مقدار روی 100 ست شده 😐
🔧 راهحل ساده ولی حیاتی بود:
مقدار user connections رو روی 0 گذاشتم
عدد 0 یعنی:
👉 SQL Server خودش مدیریت میکنه (تا حدود 32767 اتصال همزمان)
بعد از اعمال تغییر، مجبور شدیم یک بار سرویس SQL Server رو ریست کنیم 🔄
و… مشکل بهطور کامل حل شد ✅
✨ نکته جالبتر؟
کاربران میگفتن حتی سرعت سیستم هم بهتر شده!
احتمالاً سیستم مدام سعی میکرد اتصال بگیره، خطا میخورد و منتظر میموند تا دوباره تلاش کنه ⏳
🧠 جمعبندی مهم:
هر عددی که در SQL Server میبینید، معمولاً پشتش یک منطق و سناریو وجود داره.
این تنظیمات رو:
❌ با حدس
❌ با سلیقه
❌ یا «ببینیم با کدوم عدد حال میکنیم»
نباید تغییر داد!
⚠️ یک عدد اشتباه، خیلی راحت میتونه کل یک شرکت رو دچار اختلال کنه.
کمی دقت بیشتر در این جزئیات، هزینههای خیلی بزرگی رو کم میکنه.
#SQLServer #DBA #Performance #Troubleshooting #Database #Production #Experience
🔍 یک چالش جالب در SQL Server که میتونست یک مجموعه رو زمینگیر کنه!
چند وقت پیش در یکی از مجموعهها با یک مشکل عجیب مواجه بودن 👀
سیستم از یک تعداد کاربر مشخص به بعد خطا میداد و اجازه نمیداد اتصال جدیدی به دیتابیس برقرار بشه.
🔎 بعد از دیدن خطا، اولین چیزی که به ذهنم رسید این بود:
احتمالاً تنظیمات user connections دستکاری شده.
مشکل اینجا بود که حتی اتصال عادی هم به دیتابیس برقرار نمیشد!
با کلی داستان و از طریق sqlcmd تونستم مستقیم به Engine وصل بشم 💪
📌 با بررسی تنظیمات:
'sp_configure 'user connections
مشخص شد مقدار روی 100 ست شده 😐
🔧 راهحل ساده ولی حیاتی بود:
مقدار user connections رو روی 0 گذاشتم
عدد 0 یعنی:
👉 SQL Server خودش مدیریت میکنه (تا حدود 32767 اتصال همزمان)
بعد از اعمال تغییر، مجبور شدیم یک بار سرویس SQL Server رو ریست کنیم 🔄
و… مشکل بهطور کامل حل شد ✅
✨ نکته جالبتر؟
کاربران میگفتن حتی سرعت سیستم هم بهتر شده!
احتمالاً سیستم مدام سعی میکرد اتصال بگیره، خطا میخورد و منتظر میموند تا دوباره تلاش کنه ⏳
🧠 جمعبندی مهم:
هر عددی که در SQL Server میبینید، معمولاً پشتش یک منطق و سناریو وجود داره.
این تنظیمات رو:
❌ با حدس
❌ با سلیقه
❌ یا «ببینیم با کدوم عدد حال میکنیم»
نباید تغییر داد!
⚠️ یک عدد اشتباه، خیلی راحت میتونه کل یک شرکت رو دچار اختلال کنه.
کمی دقت بیشتر در این جزئیات، هزینههای خیلی بزرگی رو کم میکنه.
#SQLServer #DBA #Performance #Troubleshooting #Database #Production #Experience
❤20👍7👌2
سلام دوستان
📉 Shrink در SQL Server به روایت یک فضای کار اشتراکی!
فرض کن یکی میره یه فضای کار اشتراکی 🏢
اوایل کارش کوچیکه، یه میز اشتراکی میگیره.
کمکم کارش میگیره 📈، میگه «نه، من یه اتاق میخوام» 🚪
اتاق رو میگیره، کارش راه میافته، همه چی خوبه 😌
فرداش چی؟
میگه «نه بابا، الان اتاق زیادیه»
اتاق رو پس میده، برمیگرده میز اشتراکی 😐
عصر دوباره کار زیاد میشه:
«بچهها اتاق بدین!»
دوباره اتاق میگیره…
پس میده…
میگیره…
پس میده… 🤦♂️
حالا صاحب فضای کار اشتراکی کلافه نشده؟
دیوارها جابهجا نمیشن؟
نظم فضا به هم نمیریزه؟ 😵
📌 Shrink توی SQL Server دقیقاً همینه!
دیتابیس رشد میکنه 📊
شما Shrink میکنی چون «فضا خالیه»
دوباره دیتا میاد، دوباره رشد میکنه
دوباره Shrink
نتیجه؟
Fragmentation شدید 🧩
فشار بیخودی به IO 💥
بدتر شدن Performance 🐌
📢 Shrink یعنی پس گرفتن فضا، نه مدیریت فضا!
Shrink برای شرایط خاصه:
بعد از حذف دائمی حجم عظیمی از دیتا
وقتی مطمئنی دیگه به اون فضا نیاز نداری
نه برای اینکه:
❌ هر هفته دیسک خالی ببینی
❌ یا وجدان DBAت آروم بشه 😄
و این مساله هم برای فایل LDF صدق می کنه هم MDF.
بارها توی همه Job ها من Job برای Shrink دیدم و ایجاد Fragmentation بر روی LDF ها.
🎯 نتیجه:
به جای این همه «اتاق پس بده، اتاق بگیر»
یه فضای مناسب بگیر، درست استفاده کن،
و بگذار دیتابیس با آرامش رشد کنه
و برای کنترل LDF هم تهیه بکاپ منظم از Log ها به این مساله به شدت کمک می کنه.🧘♂️
hashtag#SQLServer hashtag#DBA hashtag#Shrink hashtag#Performance hashtag#DatabaseLife hashtag#طنز_فنی 😄
📉 Shrink در SQL Server به روایت یک فضای کار اشتراکی!
فرض کن یکی میره یه فضای کار اشتراکی 🏢
اوایل کارش کوچیکه، یه میز اشتراکی میگیره.
کمکم کارش میگیره 📈، میگه «نه، من یه اتاق میخوام» 🚪
اتاق رو میگیره، کارش راه میافته، همه چی خوبه 😌
فرداش چی؟
میگه «نه بابا، الان اتاق زیادیه»
اتاق رو پس میده، برمیگرده میز اشتراکی 😐
عصر دوباره کار زیاد میشه:
«بچهها اتاق بدین!»
دوباره اتاق میگیره…
پس میده…
میگیره…
پس میده… 🤦♂️
حالا صاحب فضای کار اشتراکی کلافه نشده؟
دیوارها جابهجا نمیشن؟
نظم فضا به هم نمیریزه؟ 😵
📌 Shrink توی SQL Server دقیقاً همینه!
دیتابیس رشد میکنه 📊
شما Shrink میکنی چون «فضا خالیه»
دوباره دیتا میاد، دوباره رشد میکنه
دوباره Shrink
نتیجه؟
Fragmentation شدید 🧩
فشار بیخودی به IO 💥
بدتر شدن Performance 🐌
📢 Shrink یعنی پس گرفتن فضا، نه مدیریت فضا!
Shrink برای شرایط خاصه:
بعد از حذف دائمی حجم عظیمی از دیتا
وقتی مطمئنی دیگه به اون فضا نیاز نداری
نه برای اینکه:
❌ هر هفته دیسک خالی ببینی
❌ یا وجدان DBAت آروم بشه 😄
و این مساله هم برای فایل LDF صدق می کنه هم MDF.
بارها توی همه Job ها من Job برای Shrink دیدم و ایجاد Fragmentation بر روی LDF ها.
🎯 نتیجه:
به جای این همه «اتاق پس بده، اتاق بگیر»
یه فضای مناسب بگیر، درست استفاده کن،
و بگذار دیتابیس با آرامش رشد کنه
و برای کنترل LDF هم تهیه بکاپ منظم از Log ها به این مساله به شدت کمک می کنه.🧘♂️
hashtag#SQLServer hashtag#DBA hashtag#Shrink hashtag#Performance hashtag#DatabaseLife hashtag#طنز_فنی 😄
👍14👌6🙏2🤨2❤1
سلام دوستان
💼🌳 چالش همیشگی ما با درختهای سلسلهمراتبی در SQL!
همیشه وقتی با ساختار درختی کار میکنیم، معمولاً از ریشه شروع میکنیم و تا برگها میرویم.
اما یه سؤال جالب پیش میاد:
❓ فرض کنید شما یه نقطه وسط درخت دارید و میخواید بفهمید این رکورد به کدوم ریشه یا مدیر اصلی وصل میشه؟
برای مثال: مشخصات یک کارمند را دارید و میخواید ببینید در چارت سازمانی، مسیرش تا مدیر ارشد کجاست.
اینجاست که باید برعکس فکر کنید: از پایین به بالا حرکت کنید، نه از بالا به پایین.
و نکته جالب: در کدنویسی و SQL، مدل بازگشتی فرقی نمیکنه، فقط جهت پیمایش عوض میشه 😎
🔹 ساختار جدول عمومی (میتونید تست کنید)
Id → شناسه رکورد
ParentId → شناسه والد (NULL یعنی ریشه)
Name → نام رکورد
🔹 کوئری CTE برای پیدا کردن مسیر تا ریشه
اگر فقط ریشه براتون مهمه:
🔹 نکات حرفهای 💡
برای هر عمق درختی جواب میده
مناسب گزارشها، داشبوردها و تحلیل سلسلهمراتبی
میتونید مسیر رو به صورت رشته /Root/Parent/Child/... هم بسازید تا راحت نمایش بدید
🧠 تجربه شخصی:
وقتی شما از پایین شروع میکنید و مسیر تا ریشه رو پیدا میکنید، دید کاملتری نسبت به سلسلهمراتب پیدا میکنید.
مثل اینه که بفهمید یک کارمند دقیقاً تحت چه مدیریتی و چه شاخهای از سازمان قرار گرفته.
💼🌳 چالش همیشگی ما با درختهای سلسلهمراتبی در SQL!
همیشه وقتی با ساختار درختی کار میکنیم، معمولاً از ریشه شروع میکنیم و تا برگها میرویم.
اما یه سؤال جالب پیش میاد:
❓ فرض کنید شما یه نقطه وسط درخت دارید و میخواید بفهمید این رکورد به کدوم ریشه یا مدیر اصلی وصل میشه؟
برای مثال: مشخصات یک کارمند را دارید و میخواید ببینید در چارت سازمانی، مسیرش تا مدیر ارشد کجاست.
اینجاست که باید برعکس فکر کنید: از پایین به بالا حرکت کنید، نه از بالا به پایین.
و نکته جالب: در کدنویسی و SQL، مدل بازگشتی فرقی نمیکنه، فقط جهت پیمایش عوض میشه 😎
🔹 ساختار جدول عمومی (میتونید تست کنید)
CREATE TABLE Table1
(
Id UNIQUEIDENTIFIER PRIMARY KEY,
Name NVARCHAR(100),
ParentId UNIQUEIDENTIFIER NULL
);
Id → شناسه رکورد
ParentId → شناسه والد (NULL یعنی ریشه)
Name → نام رکورد
🔹 کوئری CTE برای پیدا کردن مسیر تا ریشه
DECLARE @InputId UNIQUEIDENTIFIER = 'YOUR_RECORD_ID_HERE';
WITH ReverseCTE AS
(
-- شروع از رکورد مورد نظر
SELECT Id, ParentId, Name, 0 AS Level
FROM Table1
WHERE Id = @InputId
UNION ALL
-- پیمایش به سمت والد
SELECT p.Id, p.ParentId, p.Name, c.Level + 1
FROM Table1 p
INNER JOIN ReverseCTE c ON c.ParentId = p.Id
WHERE c.ParentId IS NOT NULL
)
SELECT *
FROM ReverseCTE
ORDER BY Level DESC; -- ریشه بالای خروجی
اگر فقط ریشه براتون مهمه:
SELECT TOP 1 Id, Name
FROM ReverseCTE
ORDER BY Level DESC;
🔹 نکات حرفهای 💡
برای هر عمق درختی جواب میده
مناسب گزارشها، داشبوردها و تحلیل سلسلهمراتبی
میتونید مسیر رو به صورت رشته /Root/Parent/Child/... هم بسازید تا راحت نمایش بدید
🧠 تجربه شخصی:
وقتی شما از پایین شروع میکنید و مسیر تا ریشه رو پیدا میکنید، دید کاملتری نسبت به سلسلهمراتب پیدا میکنید.
مثل اینه که بفهمید یک کارمند دقیقاً تحت چه مدیریتی و چه شاخهای از سازمان قرار گرفته.
❤6👍2