Caching جداول Temp در SQL Server 2014 بهینه شده است!

Caching جداول Temp در SQL Server 2014 بهینه شده است!

نوشته شده توسط: تورج عزیزی
۱۶ آبان ۱۳۹۴
زمان مطالعه: 14 دقیقه
۰
(۰)

مقدمه

در این مقاله با قابلیتی جدید در SQL Server آشنا می شوید که تاثیر بسزایی در Performance دیتابیس tempdb دارد.
جداول Temp جداولی هستند که در دیتابیس tempdb ساخته می شوند و نام آنها با # شروع می شود.
در صورت برقراری شرایطی خاص SQL Server می تواند جداول Temp را Cache کند. Cache کردن جداول Tempبدان معنی است که SQL Server مجبور نخواهد بود جداول Temp را هنگامی که به دفعات نیاز به ایجاد آنها دارد، بسازد. این امر کارایی workload (منظور کوئری هایی که نیاز به ساخت این جداول دارند) را به طرز فوق العاده ای بهبود می بخشد، چون SQL Server نیازی ندارد تا به Page های ویژه ای در حافظه (PFS, GAM, SGAM) دست پیدا کند که می تواند منجر به بروز درگیری در زمان peak کاری شود.
یکی از نیازمندی های Cache جداول Temp این است که شما نباید دستورات DML و DDLرا در یک Stored Procedure با هم تلفیق کنید. کد زیر را تصور کنید:
 -- Create a new stored procedure
CREATE PROCEDURE PopulateTempTable
AS
BEGIN
-- Create a new temp table
CREATE TABLE #TempTable
(
Col1 INT IDENTITY(1, 1),
Col2 CHAR(4000),
Col3 CHAR(4000)
)
-- Create a unique clustered index on the previous created temp table
CREATE UNIQUE CLUSTERED INDEX idx_c1 ON #TempTable(Col1)
-- Insert 10 dummy records
DECLARE @i INT = 0
WHILE (@i < 10)
BEGIN
INSERT INTO #TempTable VALUES ('Klaus', 'Aschenbrenner')
SET @i += 1
END
END
GO

در کدهای بالا با استفاده از یک دستور (CREATE UNIQUE CLUSTERED INDEX) که یک دستور از نوع DDL است یک ایندکس ایجاد می کنید و بدین معنی است که دستورات DDL و DML را با هم تلفیق کرده اید. به این دلیل SQL Server  نمی تواند جداول شما را Cache کند.

شما می توانید از وجود چنین رفتاری مطمئن شوید. کافیست یک Perfrormance Counter به نام Temp Tables Creation Rate در یک dmv به نام sys.dm_os_performance_counters مانند مثال زیر بررسی کنید:
DECLARE @table_counter_before_test BIGINT;
SELECT @table_counter_before_test = cntr_value FROM sys.dm_os_performance_counters
WHERE counter_name = 'Temp Tables Creation Rate'
DECLARE @i INT = 0
WHILE (@i < 1000)
BEGIN
EXEC PopulateTempTable
SET @i += 1
END
DECLARE @table_counter_after_test BIGINT;
SELECT @table_counter_after_test = cntr_value FROM sys.dm_os_performance_counters
WHERE counter_name = 'Temp Tables Creation Rate'
PRINT 'Temp tables created during the test: ' + CONVERT(VARCHAR(100), @table_counter_after_test - @table_counter_before_test)
GO
وقتی شما کدهای بالا را اجرا می کنید SQL Server باید ۱۰۰۰ جدول temp بسازد. این موضوع در خروجی SSMS قابل مشاهده است:
برای رفع این مشکل می توانید با استفاده از قید PRIMARY KEY یک Clustered Unique Index بسازید. با این روش شما بدون استفاده از دستور DDL به هدف خود رسیده اید و در نهایت SQL Server می تواند جداول شما را Cache کند.
ALTER PROCEDURE PopulateTempTable
AS
BEGIN
-- Create a new temp table
CREATE TABLE #TempTable
(
Col1 INT IDENTITY(1, 1) PRIMARY KEY, -- This creates also a Unique Clustered Index
Col2 CHAR(4000),
Col3 CHAR(4000)
)
-- Insert 10 dummy records
DECLARE @i INT = 0
WHILE (@i < 10)
BEGIN
INSERT INTO #TempTable VALUES ('Klaus', 'Aschenbrenner')
SET @i += 1
END
END
GO

اگر یک بار دیگر کد آزمایش Perfrormance Counter را اجرا کنید خواهید دید که  SQL Server جدول temp را یکبار ساخته و به دفعات از آن استفاده کرده است.

اگر با استفاده از دستورات DDL دیگر ایندکس های Nonclustered دیگری روی جدول temp بسازید، باز هم جدول temp قادر به Cache شدن نخواهد بود. در SQL Server 2014 برای رفع این مشکل می توانید اینگونه ایندکس ها را به روش Inline تعریف کنید:
ALTER PROCEDURE PopulateTempTable
AS
BEGIN
-- Create a new temp table
CREATE TABLE #TempTable
(
Col1 INT IDENTITY(1, 1) PRIMARY KEY, -- This creates also a Unique Clustered Index
Col2 CHAR(100) INDEX idx_Col2,
Col3 CHAR(100) INDEX idx_Col3
)
-- Insert 10 dummy records
DECLARE @i INT = 0
WHILE (@i < 10)
BEGIN
INSERT INTO #TempTable VALUES ('Klaus', 'Aschenbrenner')
SET @i += 1
END
END
GO
همانطوری که می بینید من دو ایندکس Nonclustered روی جدول temp مستقیماً هنگام ساخت جدول ایجاد کرده ام و مجدداً این بدان معنی است که ما دستورات DDL و DML را با هم تلفیق نکرده ایم.
امکان تعریف ایندکس روی جداول temp هنگام تعریف جدول یک قابلیت بسیار عالی در SQL Server 2014 محسوب می شود.
در مورد این قابلیت چطور فکر میکنید؟

چه رتبه ای می‌دهید؟

میانگین ۰ / ۵. از مجموع ۰

اولین نفر باش

title sign
معرفی نویسنده
تورج عزیزی
مقالات
17 مقاله توسط این نویسنده
محصولات
0 دوره توسط این نویسنده
تورج عزیزی
پروفایل نویسنده
title sign
معرفی محصول
مسعود طاهری

دوره آموزشی Performance Tuning در SQL Server (گروه 15)

ثبت نام حضوری8.700.000 تومان
ثبت نام غیرحضوری5.700.000 تومان
title sign
دیدگاه کاربران

    •    با سلام

      من تست کردم بر روی سرعت خیلی تاثیر گذار است واقعا از مقاله خوبتون ممنونم

      با تشکر از شما

    •    با سلام

      من تست کردم بر روی سرعت خیلی تاثیر گذار است واقعا از مقاله خوبتون ممنونم

      با تشکر از شما

    •     بسیار عالی

    •     بسیار عالی

    •    فرشید علی اکبری:

       با ۸ فایل شروع کنید و مانیتور کنید، در صورت وجود Bottleneck ، 
      ۴ فایل اضافه کنید و دوباره بررسی کنید  وجود Bottleneck را چک کنید و این روند را تا زمانی که  Bottleneck از بین برود ادامه دهید.
    •    فرشید علی اکبری:

       با ۸ فایل شروع کنید و مانیتور کنید، در صورت وجود Bottleneck ، 
      ۴ فایل اضافه کنید و دوباره بررسی کنید  وجود Bottleneck را چک کنید و این روند را تا زمانی که  Bottleneck از بین برود ادامه دهید.
    •    سلام

      مقاله بسیار عالی و کاربردی بود
      سپاسگذار
    •    سلام

      مقاله بسیار عالی و کاربردی بود
      سپاسگذار
    • دوستان عزیز برای مشاهده پیج های allocated شده و deallocated شده به ازای هر Session در بانک اطلاعاتی TempDB می توانید از ویو dm_db_session_space_usage استفاده کنید به مثال زیر توجه کنید

          USE master

      GO
      —ایجاد جدول موقت
      CREATE TABLE #TempTable ( ID INT ,Name char(8000)) ;
      GO
      —درج رکورد تستی
      INSERT INTO #TempTable ( ID,Name ) VALUES ( 1,’AAAAAA’ ) ;
      INSERT INTO #TempTable ( ID,Name ) VALUES ( 2,’BBBBBB’ ) ;
      INSERT INTO #TempTable ( ID,Name ) VALUES ( 3,’CCCCCC’ ) ;
      GO
      —تعداد پیج های تخصیص یافته
      SELECT 
          session_id,
          database_id,
          DB_NAME(database_id),
          user_objects_alloc_page_count
      FROM sys.dm_db_session_space_usage
      WHERE session_id =@@SPID ;
      GO
      —مشاهده پیج ها مربوط به جدول
      DBCC IND(‘TEMPDB’,’#TempTable’,-1)
      GO
      —مشاهده محتوای پیج
      DBCC TRACEON(3604)
      DBCC PAGE(‘TEMPDB’,1,341,3)
      GO
      –مشاهده لاگ های درج شده در لاگ فایل
      USE tempdb
      GO
      SELECT [Current LSN],[Transaction ID],Operation FROM SYS.fn_dblog(NULL,NULL)
      ضمنا یکی از مهمترین دلایل افزایش دیتا فایل های TempDB کاهش Latch Contention می باشد.
    • دوستان عزیز برای مشاهده پیج های allocated شده و deallocated شده به ازای هر Session در بانک اطلاعاتی TempDB می توانید از ویو dm_db_session_space_usage استفاده کنید به مثال زیر توجه کنید

          USE master

      GO
      —ایجاد جدول موقت
      CREATE TABLE #TempTable ( ID INT ,Name char(8000)) ;
      GO
      —درج رکورد تستی
      INSERT INTO #TempTable ( ID,Name ) VALUES ( 1,’AAAAAA’ ) ;
      INSERT INTO #TempTable ( ID,Name ) VALUES ( 2,’BBBBBB’ ) ;
      INSERT INTO #TempTable ( ID,Name ) VALUES ( 3,’CCCCCC’ ) ;
      GO
      —تعداد پیج های تخصیص یافته
      SELECT 
          session_id,
          database_id,
          DB_NAME(database_id),
          user_objects_alloc_page_count
      FROM sys.dm_db_session_space_usage
      WHERE session_id =@@SPID ;
      GO
      —مشاهده پیج ها مربوط به جدول
      DBCC IND(‘TEMPDB’,’#TempTable’,-1)
      GO
      —مشاهده محتوای پیج
      DBCC TRACEON(3604)
      DBCC PAGE(‘TEMPDB’,1,341,3)
      GO
      –مشاهده لاگ های درج شده در لاگ فایل
      USE tempdb
      GO
      SELECT [Current LSN],[Transaction ID],Operation FROM SYS.fn_dblog(NULL,NULL)
      ضمنا یکی از مهمترین دلایل افزایش دیتا فایل های TempDB کاهش Latch Contention می باشد.
  • 1
  • 2