۱۴۰۴/۰۷/۰۵ Nebular

انواع تیبل ها

✅ Table Variable vs Temporary Table — تفاوت کامل

ویژگیTemporary Table (#Temp)Table Variable (@TableVar)
محل ذخیره‌سازیدر TempDB ایجاد می‌شوددر TempDB ایجاد می‌شود (برخلاف تصور برخی که فکر می‌کنند در حافظه است!)
قابلیت ایجاد Indexمی‌توان Index تعریف کردفقط Primary Key یا Unique Constraint قابل ایجاد است
پشتیبانی از Statistics (آمار داده)دارد ✅ → باعث بهینه بودن Query Plan می‌شودندارد ❌ → ممکن است باعث کندی شود
قلمرو (Scope)تا پایان Connection یا تا وقتی DROP شودفقط داخل همان Batch یا Stored Procedure
مناسب برای حجم داده زیاد؟بله ✅خیر ❌ (کند می‌شود)
Transaction Behaviorتحت تأثیر Transaction و Rollback قرار می‌گیرد ✅خارج از Rollback باقی می‌ماند ❌
امکان استفاده با SELECT INTOبله ✅خیر ❌ (باید صراحتاً تعریف شود)

🎯 در چه مواقعی از کدام استفاده کنیم؟

✅ از Temporary Table (#Temp) استفاده کن وقتی:

  • حجم داده زیاد است
  • نیاز به Index یا Statistics برای بهینه‌سازی داری
  • می‌خواهی چندبار روی آن عملیات انجام دهی (Join, Update, Delete)

✅ از Table Variable (@TableVar) استفاده کن وقتی:

  • حجم داده کم است
  • فقط یک بار استفاده می‌شود
  • داخل Function یا Stored Procedure کوچک استفاده می‌کنی

🧪 مثال مقایسه عملکرد

-- Temporary Table
CREATE TABLE #Temp (ID INT, Name NVARCHAR(50));
INSERT INTO #Temp VALUES (1, 'Ali'), (2, 'Sara');
SELECT * FROM #Temp;

-- Table Variable
DECLARE @TableVar TABLE (ID INT, Name NVARCHAR(50));
INSERT INTO @TableVar VALUES (1, 'Ali'), (2, 'Sara');
SELECT * FROM @TableVar;

ظاهر یکی است، اما از نظر Performance و Behavior کاملاً فرق دارند.


🧠 جمع‌بندی استادانه

اگر…انتخاب مناسب
داده کم است و فقط استفاده سریع لازم داری@TableVar (Table Variable)
داده زیاد است، می‌خواهی Join / Index بزنی#Temp (Temporary Table)
داخل Transaction کار می‌کنی و می‌خواهی Rollback شود#Temp
داخل Function هستیفقط @TableVar قابل استفاده است

✅ تفاوت Table Variable / Temporary Table با Indexed View

ویژگیTemporary Table (#Temp)Table Variable (@TableVar)Indexed View (WITH SCHEMABINDING + INDEX)
نوعجدول موقتیجدول موقتی در محدوده BatchView دائمی + ایندکس ذخیره‌شده
محل ذخیرهTempDBTempDBپایگاه داده اصلی (نه TempDB)
زمان ایجاددر زمان اجرادر زمان اجرایک‌بار ساخته می‌شود و همیشه پابرجاست
قابلیت ایجاد ایندکسدستیمحدود (فقط PK/Unique)ایندکس خوشه‌ای دائم دارد
Lifetimeموقتی (تا پایان Connection یا Scope)فقط داخل همان Batchدائمی مثل یک جدول
مناسب برای Join و عملیات پیچیده؟بلهبرای دیتا کمعالی مخصوصاً در Queryهای تکراری
مناسب برای ذخیره Result Set موقت؟بلهبرای دیتا کمخیر (برای این کار طراحی نشده)
بهینه‌سازی عملکرد Queryهای تکراریمعمولیضعیف‌ترعالی ✅

🎯 Indexed View دقیقاً چیست؟

یک View معمولی فقط یک Query ذخیره شده‌ست. ولی Indexed View وقتی Index داشته باشد، نتیجه‌اش به صورت فیزیکی (Materialized) ذخیره می‌گردد. یعنی مثل یک جدول واقعی رفتار می‌کند و هر بار Query اجرا نمی‌شود.

مثال واقعی:

CREATE VIEW dbo.vw_SalesSummary
WITH SCHEMABINDING
AS
SELECT CustomerID, SUM(TotalAmount) AS TotalSales
FROM dbo.Sales
GROUP BY CustomerID;
GO

CREATE UNIQUE CLUSTERED INDEX IX_vw_SalesSummary
ON dbo.vw_SalesSummary (CustomerID);

✅ حالا هر وقت Query بزنیم:

SELECT * FROM dbo.vw_SalesSummary WHERE CustomerID = 10;

SQL Server سراغ دیتاهای آماده در ایندکس می‌رود → سرعت بسیار بالا!


🧠 پس فرق اصلی Indexed View با Temp Table / Table Variable چیست؟

| اگر هدف تو نگهداری موقت داده در وسط یک Query یا Procedure است → از Temp Table یا Table Variable استفاده کن. |

| اگر هدف تو بهینه‌سازی یک Query سنگین و تکراری است → از Indexed View استفاده کن. |


📌 جمع‌بندی استادانه

نیازانتخاب مناسب
ذخیره موقت داده داخل Procedure#Temp یا @TableVar
سرعت بیشتر در Queryهای تکراری و محاسبات AggregationIndexed View
ایندکس‌گذاری سنگین و Join زیاد#Temp بهتر از @TableVar
کاهش لود CPU در گزارش‌گیریIndexed View بهترین گزینه است

اگر خواستی، می‌تونم:

  • Indexed View را با Table Comparison Benchmark بزنم
  • یا سناریو طراحی کنم که Indexed View باعث ۱۰ برابر سریع‌تر شدن Query بشود

✅ تفاوت Table Variable / Temporary Table با Indexed View

ویژگیTemporary Table (#Temp)Table Variable (@TableVar)Indexed View (WITH SCHEMABINDING + INDEX)
نوعجدول موقتیجدول موقتی در محدوده BatchView دائمی + ایندکس ذخیره‌شده
محل ذخیرهTempDBTempDBپایگاه داده اصلی (نه TempDB)
زمان ایجاددر زمان اجرادر زمان اجرایک‌بار ساخته می‌شود و همیشه پابرجاست
قابلیت ایجاد ایندکسدستیمحدود (فقط PK/Unique)ایندکس خوشه‌ای دائم دارد
Lifetimeموقتی (تا پایان Connection یا Scope)فقط داخل همان Batchدائمی مثل یک جدول
مناسب برای Join و عملیات پیچیده؟بلهبرای دیتا کمعالی مخصوصاً در Queryهای تکراری
مناسب برای ذخیره Result Set موقت؟بلهبرای دیتا کمخیر (برای این کار طراحی نشده)
بهینه‌سازی عملکرد Queryهای تکراریمعمولیضعیف‌ترعالی ✅

🎯 Indexed View دقیقاً چیست؟

یک View معمولی فقط یک Query ذخیره شده‌ست. ولی Indexed View وقتی Index داشته باشد، نتیجه‌اش به صورت فیزیکی (Materialized) ذخیره می‌گردد. یعنی مثل یک جدول واقعی رفتار می‌کند و هر بار Query اجرا نمی‌شود.

مثال واقعی:

CREATE VIEW dbo.vw_SalesSummary
WITH SCHEMABINDING
AS
SELECT CustomerID, SUM(TotalAmount) AS TotalSales
FROM dbo.Sales
GROUP BY CustomerID;
GO

CREATE UNIQUE CLUSTERED INDEX IX_vw_SalesSummary
ON dbo.vw_SalesSummary (CustomerID);

✅ حالا هر وقت Query بزنیم:

SELECT * FROM dbo.vw_SalesSummary WHERE CustomerID = 10;

SQL Server سراغ دیتاهای آماده در ایندکس می‌رود → سرعت بسیار بالا!


🧠 پس فرق اصلی Indexed View با Temp Table / Table Variable چیست؟

| اگر هدف تو نگهداری موقت داده در وسط یک Query یا Procedure است → از Temp Table یا Table Variable استفاده کن. |

| اگر هدف تو بهینه‌سازی یک Query سنگین و تکراری است → از Indexed View استفاده کن. |


📌 جمع‌بندی استادانه

نیازانتخاب مناسب
ذخیره موقت داده داخل Procedure#Temp یا @TableVar
سرعت بیشتر در Queryهای تکراری و محاسبات AggregationIndexed View
ایندکس‌گذاری سنگین و Join زیاد#Temp بهتر از @TableVar
کاهش لود CPU در گزارش‌گیریIndexed View بهترین گزینه است

✅ مثال کاربردی ۱ — استفاده از Temporary Table برای ذخیره نتیجهٔ میانی

📌 سناریو:

فرض کن می‌خوای لیست مشتریانی که بیش از ۵ سفارش داشته‌اند را پیدا کنی، ولی قبل از فیلتر کردن، می‌خواهی جزییات سفارشات را پردازش و گروه‌بندی کنی.

-- مرحله 1: ساخت Temp Table
CREATE TABLE #CustomerOrders (
    CustomerID INT,
    TotalOrders INT
);

-- مرحله 2: پر کردن داده‌ها
INSERT INTO #CustomerOrders
SELECT CustomerID, COUNT(*) 
FROM Orders
GROUP BY CustomerID;

-- مرحله 3: استفاده از داده‌های موقت
SELECT C.CustomerName, T.TotalOrders
FROM #CustomerOrders T
JOIN Customers C ON T.CustomerID = C.CustomerID
WHERE T.TotalOrders > 5;

🔎 Trace و رفتار این Query:

مرحلهکار انجام‌شدهقفل (Lock)تاثیر روی Query Plan
ساخت #Tempذخیره روی TempDBSchema Lock✅ Optimizer می‌تواند Index روی آن بسازد
InsertBulk InsertRow Lock✅ Statistics تولید می‌شود
Select JoinFull JoinShared Lock✅ Execution Plan از Index استفاده می‌کند

نتیجه: برای دیتای زیاد عالی است، چون Statistics دارد و SQL Server می‌تواند Plan بهینه بسازد.


✅ مثال کاربردی ۲ — استفاده از Table Variable برای نگه داشتن مقدار کم

📌 سناریو:

می‌خواهیم لیست ۳ محصول پرفروش را موقتاً نگه داریم و از آن در شرط دیگری استفاده کنیم.

DECLARE @TopProducts TABLE (
    ProductID INT,
    TotalSales INT
);

INSERT INTO @TopProducts
SELECT TOP 3 ProductID, SUM(Quantity)
FROM OrderDetails
GROUP BY ProductID
ORDER BY SUM(Quantity) DESC;

-- استفاده از آن در یک شرط دیگر
SELECT * FROM Products
WHERE ProductID IN (SELECT ProductID FROM @TopProducts);

🔎 Trace رفتار Table Variable:

مرحلهرفتارنکته
ساخت @TableVarدر TempDB ساخته می‌شود اما Statistics ندارد❌ Optimizer نمی‌داند چند ردیف دارد
Insertسریع برای دیتا کم✅ مناسب برای کمتر از 100 ردیف
SelectScan کامل❌ ممکن است Join ها سنگین شوند

✅ نتیجه‌گیری استادانه

| اگر حجم داده زیاد است یا نیاز به Join و Index داری → از #Temp Table استفاده کن.
| اگر حجم داده کم و کنترلی است یا داخل Function یا Procedure کوچک هستی → از @Table Variable استفاده کن.

انواع جدول‌ها / ساختارهای داده در SQL Server (برای مقایسه با Temp & Table Variable)

نوع جدول / ساختاردوام (Persistence)محل ذخیرهScope / محدودهکاربرد اصلیقابل مقایسه با Temp؟
Permanent Table (جدول دائمی)دائمDatabase اصلیPublicذخیره اصلی دادهپایه مقایسه
Temporary Table (#Temp)موقتTempDBSession یا Procedureپردازش داده‌های موقتی سنگین
Global Temp Table (##Temp)موقتTempDBکل سرور (تا پایان آخرین Session)اشتراک موقتی بین Sessionها
Table Variable (@Table)موقتTempDBفقط Batchداده‌های کم و سبک
Common Table Expression (CTE)غیر مادی (Logical فقط)حافظهفقط همان Queryخوانایی و بازنویسی✅ به شکل محدود
Derived Table (Subquery in FROM)غیر مادیحافظهداخل همان Queryجایگزین سریع و سادهمشابه CTE
Indexed View (Materialized View)دائمDatabase اصلیعمومیبهینه‌سازی Queryهای تکراری
Memory-Optimized Table (In-Memory OLTP)دائم یا موقتRAMPublicسرعت بسیار بالا برای OLTP✅ برای مقایسه Performance
Temp Table in Memory (Table Variable + MEMORY_OPTIMIZED=ON)موقتRAMBatchنسخه پرسرعت Table Variable

مزایای temp table در stored procedure

وقتی شما داخل یک Stored Procedure از Temp Table استفاده می‌کنید، ممکنه سرعت رو به‌طور قابل توجهی افزایش بده. دلایل اصلی:


1. شکستن Queryهای پیچیده به بخش‌های کوچکتر

  • وقتی یک کوئری خیلی پیچیده با چندین JOIN، SUBQUERY یا CTE داری، SQL Server باید یک execution plan خیلی سنگین بسازه.
  • اگر نتایج میانی رو در یک Temp Table ذخیره کنی، SQL Server اون مرحله رو جداگانه محاسبه می‌کنه و برای مراحل بعدی با یک دیتاست آماده ادامه می‌ده.
  • این باعث می‌شه Plan ساده‌تر و بهینه‌تر بشه.

2. ایجاد ایندکس روی داده‌های موقت

  • روی CTE یا Derived Table نمی‌تونی ایندکس بسازی.
  • اما روی یک Temp Table می‌تونی Clustered/Non-Clustered Index تعریف کنی.
  • این کار باعث می‌شه JOIN, WHERE, GROUP BY سریع‌تر بشه.

3. کاهش تکرار محاسبات

فرض کن داخل SP یک محاسبه سنگین (مثلاً روی میلیون‌ها ردیف) چند بار نیاز داری.

  • اگر از CTE استفاده کنی، هر بار مجدداً محاسبه می‌شه.
  • ولی اگر خروجی رو یک بار در Temp Table بذاری، دفعه‌های بعد مستقیم از همون جدول خونده می‌شه.

4. کاهش فشار روی Transaction Log اصلی

  • Temp Table در tempdb ساخته می‌شه، نه در دیتابیس اصلی.
  • این یعنی تراکنش‌های موقت به Log دیتابیس اصلی اضافه نمی‌شن → کمتر شدن لاگ نویسی → سریع‌تر شدن عملیات.

5. بهبود موازی‌سازی و حافظه

  • گاهی اوقات Query Optimizer نمی‌تونه بهینه‌ترین Execution Plan رو برای یک کوئری خیلی بزرگ انتخاب کنه.
  • شکستن کار با Temp Table باعث می‌شه SQL Server بهتر بتونه حافظه رو مدیریت کنه و پردازش موازی انجام بده.

✅ نتیجه:
Temp Table سرعت Stored Procedure رو بالا می‌بره چون:

  • نتایج میانی رو ذخیره می‌کنه.
  • امکان ایندکس‌گذاری روی داده‌های موقت رو فراهم می‌کنه.
  • از محاسبات تکراری جلوگیری می‌کنه.
  • فشار روی Transaction Log اصلی رو کم می‌کنه
Accept Cookies
Accept Cookies
[your-shortcode]