একটি নির্দিষ্ট ক্ষেত্রে # টেম্প টেবিলের চেয়ে দ্বিগুণেরও বেশি দ্রুত টেবিলের পরিবর্তনশীল কেন ব্যবহার করছেন?


37

আমি এখানে নিবন্ধটি দেখছিলাম অস্থায়ী টেবিল বনাম টেবিল ভেরিয়েবল এবং এসকিউএল সার্ভারের পারফরম্যান্স এবং এসকিউএল সার্ভার ২০০ 2008 এ তাদের প্রভাব 2005 এর জন্য সেখানে প্রদর্শিত ফলাফলগুলির অনুরূপ ফলাফল পুনরুত্পাদন করতে সক্ষম হয়েছিল।

কেবলমাত্র 10 টি সারি দিয়ে সঞ্চিত প্রক্রিয়াগুলি (নীচে সংজ্ঞাগুলি) সম্পাদন করার সময় টেবিলের ভেরিয়েবল সংস্করণটি অস্থায়ী টেবিল সংস্করণটিকে দুইবারের বেশি সম্পাদন করে।

আমি পদ্ধতিটি ক্যাশে সাফ করে দিয়েছি এবং উভয় সঞ্চিত পদ্ধতি 10,000 বার চালিয়েছি এবং আরও 4 রানের জন্য প্রক্রিয়াটি পুনরাবৃত্তি করেছি। নীচে ফলাফল (প্রতি ব্যাচে এমএসে সময়)

T2_Time     V2_Time
----------- -----------
8578        2718      
6641        2781    
6469        2813   
6766        2797
6156        2719

আমার প্রশ্ন: টেবিলের পরিবর্তনশীল সংস্করণটির আরও ভাল পারফরম্যান্সের কারণ কী?

আমি কিছু তদন্ত করেছি। উদাহরণস্বরূপ পারফরম্যান্স কাউন্টারগুলির সাথে তাকানো

SELECT cntr_value
from sys.dm_os_performance_counters
where counter_name = 'Temp Tables Creation Rate';

নিশ্চিত করে যে উভয় ক্ষেত্রেই অস্থায়ী বস্তুগুলি প্রথম রান করার পরে ক্যাশে হচ্ছে জন্য পুনরায় স্ক্র্যাচ থেকে তৈরি না করে প্রত্যাশা অনুযায়ী

একইভাবে ট্রেসিং Auto Stats, SP:Recompile, SQL:StmtRecompileপ্রোফাইলার ঘটনা (নীচে স্ক্রীনশট) শো যে এই ঘটনা শুধুমাত্র এক বার (প্রথম আবাহন উপর ঘটতে #tempটেবিল সঞ্চিত পদ্ধতি) এবং অন্যান্য 9,999 মৃত্যুদণ্ড কার্যকর এই ঘটনা কোনো বাড়াতে না। (টেবিলের পরিবর্তনশীল সংস্করণ এই ইভেন্টগুলির কোনওটি পায় না)

চিহ্ন

সঞ্চিত পদ্ধতির প্রথম রানের সামান্য বৃহত্তর ওভারহেড কোনওভাবেই বড় সামগ্রিক পার্থক্যের জন্য অ্যাকাউন্ট করতে পারে না তবে পদ্ধতি ক্যাশেটি পরিষ্কার করতে এবং উভয় পদ্ধতি একবার চালাতে কেবল কয়েক এমএস লাগবে তাই আমি বিশ্বাস করি না কোনও পরিসংখ্যান বা recompiles কারণ হতে পারে।

প্রয়োজনীয় ডেটাবেস অবজেক্ট তৈরি করুন

CREATE DATABASE TESTDB_18Feb2012;

GO

USE TESTDB_18Feb2012;

CREATE TABLE NUM 
  ( 
     n INT PRIMARY KEY, 
     s VARCHAR(128) 
  ); 

WITH NUMS(N) 
     AS (SELECT TOP 1000000 ROW_NUMBER() OVER (ORDER BY $/0) 
         FROM   master..spt_values v1, 
                master..spt_values v2) 
INSERT INTO NUM 
SELECT N, 
       'Value: ' + CONVERT(VARCHAR, N) 
FROM   NUMS 

GO

CREATE PROCEDURE [dbo].[T2] @total INT 
AS 
  CREATE TABLE #T 
    ( 
       n INT PRIMARY KEY, 
       s VARCHAR(128) 
    ) 

  INSERT INTO #T 
  SELECT n, 
         s 
  FROM   NUM 
  WHERE  n%100 > 0 
         AND n <= @total 

  DECLARE @res VARCHAR(128) 

  SELECT @res = MAX(s) 
  FROM   NUM 
  WHERE  n <= @total 
         AND NOT EXISTS(SELECT * 
                        FROM   #T 
                        WHERE  #T.n = NUM.n) 
GO

CREATE PROCEDURE [dbo].[V2] @total INT 
AS 
  DECLARE @V TABLE ( 
    n INT PRIMARY KEY, 
    s VARCHAR(128)) 

  INSERT INTO @V 
  SELECT n, 
         s 
  FROM   NUM 
  WHERE  n%100 > 0 
         AND n <= @total 

  DECLARE @res VARCHAR(128) 

  SELECT @res = MAX(s) 
  FROM   NUM 
  WHERE  n <= @total 
         AND NOT EXISTS(SELECT * 
                        FROM   @V V 
                        WHERE  V.n = NUM.n) 


GO

পরীক্ষা স্ক্রিপ্ট

SET NOCOUNT ON;

DECLARE @T1 DATETIME2,
        @T2 DATETIME2,
        @T3 DATETIME2,  
        @Counter INT = 0

SET @T1 = SYSDATETIME()

WHILE ( @Counter < 10000)
BEGIN
EXEC dbo.T2 10
SET @Counter += 1
END

SET @T2 = SYSDATETIME()
SET @Counter = 0

WHILE ( @Counter < 10000)
BEGIN
EXEC dbo.V2 10
SET @Counter += 1
END

SET @T3 = SYSDATETIME()

SELECT DATEDIFF(MILLISECOND,@T1,@T2) AS T2_Time,
       DATEDIFF(MILLISECOND,@T2,@T3) AS V2_Time

প্রোফাইল ট্রেস ইঙ্গিত দেয় যে পরিসংখ্যানগুলি পরিষ্কার হয়ে যাওয়ার পরে কেবল #tempটেবিলে একবার তৈরি হয়ে যায় এবং এরপরে আরও 9,999 বার পুনরায় জনবসতি ঘটে ।
মার্টিন স্মিথ

উত্তর:


31

SET STATISTICS IO ONউভয়ের জন্য আউটপুট অনুরূপ দেখায়

SET STATISTICS IO ON;
PRINT 'V2'
EXEC dbo.V2 10
PRINT 'T2'
EXEC dbo.T2 10

দেয়

V2
Table '#58B62A60'. Scan count 0, logical reads 20
Table 'NUM'. Scan count 1, logical reads 3

Table '#58B62A60'. Scan count 10, logical reads 20
Table 'NUM'. Scan count 1, logical reads 3

T2
Table '#T__ ... __00000000E2FE'. Scan count 0, logical reads 20
Table 'NUM'. Scan count 1, logical reads 3

Table '#T__ ... __00000000E2FE'. Scan count 0, logical reads 20
Table 'NUM'. Scan count 1, logical reads 3

এবং হিসাবে হারুন মন্তব্য তুলে ধরে টেবিল পরিবর্তনশীল সংস্করণের জন্য পরিকল্পনা আসলে কম কার্যকরী উভয় থাকাকালীন উপর চাইতে আছে নেস্টেড loops পরিকল্পনা সূচক দ্বারা চালিত টেবিল সংস্করণ সঞ্চালিত একটি উপর সূচক মধ্যে নেওয়া অবশিষ্ট সম্পৃক্ত সঙ্গে যেহেতু টেবিল পরিবর্তনশীল সংস্করণ অবশিষ্ট সূচক নিয়ে একটি সূচক অনুসন্ধান সম্পাদন করে এবং আরও বেশি সারি প্রক্রিয়াজাত করে (যার কারণে এই পরিকল্পনাটি বৃহত্তর সংখ্যক সারিগুলির জন্য এত খারাপভাবে সম্পাদন করে)dbo.NUM#temp[#T].n = [dbo].[NUM].[n][#T].[n]<=[@total]@V.n <= [@total]@V.[n]=[dbo].[NUM].[n]

নির্দিষ্ট স্পিডের জন্য অপেক্ষা প্রকারগুলি দেখার জন্য বর্ধিত ইভেন্টগুলি ব্যবহার করে 10,000 এর মৃত্যুদণ্ড কার্যকর করা হয়EXEC dbo.T2 10

+---------------------+------------+----------------+----------------+----------------+
|                     |            |     Total      | Total Resource |  Total Signal  |
| Wait Type           | Wait Count | Wait Time (ms) | Wait Time (ms) | Wait Time (ms) |
+---------------------+------------+----------------+----------------+----------------+
| SOS_SCHEDULER_YIELD | 16         | 19             | 19             | 0              |
| PAGELATCH_SH        | 39998      | 14             | 0              | 14             |
| PAGELATCH_EX        | 1          | 0              | 0              | 0              |
+---------------------+------------+----------------+----------------+----------------+

এবং 10,000 এর মৃত্যুদণ্ড কার্যকর করার জন্য এই ফলাফলগুলি EXEC dbo.V2 10

+---------------------+------------+----------------+----------------+----------------+
|                     |            |     Total      | Total Resource |  Total Signal  |
| Wait Type           | Wait Count | Wait Time (ms) | Wait Time (ms) | Wait Time (ms) |
+---------------------+------------+----------------+----------------+----------------+
| PAGELATCH_EX        | 2          | 0              | 0              | 0              |
| PAGELATCH_SH        | 1          | 0              | 0              | 0              |
| SOS_SCHEDULER_YIELD | 676        | 0              | 0              | 0              |
+---------------------+------------+----------------+----------------+----------------+

সুতরাং এটি পরিষ্কার যে টেবিলের ক্ষেত্রে PAGELATCH_SHঅপেক্ষাগুলির সংখ্যা অনেক বেশি #temp। আমি আরও দৌড়ে গিয়েছি কিনা তা তদন্ত করতে বর্ধিত ইভেন্টগুলির ট্রেসগুলিতে অপেক্ষা সংস্থান যুক্ত করার কোনও উপায় সম্পর্কে আমি অবগত নই

WHILE 1=1
EXEC dbo.T2 10

অন্য সংযোগের ভোটগ্রহণের সময় sys.dm_os_waiting_tasks

CREATE TABLE #T(resource_description NVARCHAR(2048))

WHILE 1=1
INSERT INTO #T
SELECT resource_description
FROM sys.dm_os_waiting_tasks
WHERE session_id=<spid_of_other_session> and wait_type='PAGELATCH_SH'

প্রায় 15 সেকেন্ডের জন্য এই দৌড়াতে যাওয়ার পরে এটি নিম্নলিখিত ফলাফলগুলি সংগ্রহ করেছিল

+-------+----------------------+
| Count | resource_description |
+-------+----------------------+
|  1098 | 2:1:150              |
|  1689 | 2:1:146              |
+-------+----------------------+

এই উভয় পৃষ্ঠাগুলি ল্যাচ করা হচ্ছে এবং tempdb.sys.sysschobjsবেস টেবিলের নামযুক্ত 'nc1'ও (বিভিন্ন) নন ক্লাস্টারযুক্ত সূচকের অন্তর্ভুক্ত'nc2'

tempdb.sys.fn_dblogরান চলাকালীন জিজ্ঞাসা করা ইঙ্গিত দেয় যে প্রতিটি সঞ্চিত পদ্ধতির প্রথম সম্পাদন দ্বারা যুক্ত লগ রেকর্ডের সংখ্যা কিছুটা পরিবর্তনশীল তবে পরবর্তী মৃত্যুদন্ড কার্যকর করার জন্য প্রতিটি পুনরাবৃত্তির দ্বারা যুক্ত সংখ্যাটি খুব সামঞ্জস্যপূর্ণ এবং অনুমানযোগ্য ছিল। প্রক্রিয়া পরিকল্পনাগুলি একবার ক্যাশে হয়ে গেলে লগ এন্ট্রিগুলির সংখ্যা #tempসংস্করণের জন্য প্রয়োজনীয় অর্ধেক হয়ে যায় ।

+-----------------+----------------+------------+
|                 | Table Variable | Temp Table |
+-----------------+----------------+------------+
| First Run       |            126 | 72 or 136  |
| Subsequent Runs |             17 | 32         |
+-----------------+----------------+------------+

#tempএসপি- র টেবিল সংস্করণের জন্য আরও বিশদে লেনদেন লগ এন্ট্রিগুলি সন্ধান করে সঞ্চিত পদ্ধতির প্রতিটি পরবর্তী অনুরোধ তিনটি লেনদেন এবং টেবিলের পরিবর্তনশীল একটি মাত্র দুটি তৈরি করে।

+---------------------------------+----+---------------------------------+----+
|           #Temp Table                |         @Table Variable              |
+---------------------------------+----+---------------------------------+----+
| CREATE TABLE                    |  9 |                                 |    |
| INSERT                          | 12 | TVQuery                         | 12 |
| FCheckAndCleanupCachedTempTable | 11 | FCheckAndCleanupCachedTempTable |  5 |
+---------------------------------+----+---------------------------------+----+

INSERT/ TVQUERYলেনদেনের নাম ছাড়া অভিন্ন। এটি অস্থায়ী টেবিল বা টেবিল ভেরিয়েবলের সাথে 10 টি সারি সন্নিবেশ করানো লগ রেকর্ডস অন্তর্ভুক্ত করে LOP_BEGIN_XACT/LOP_COMMIT_XACT এন্ট্রিগুলিতে ।

CREATE TABLEলেনদেন শুধুমাত্র প্রদর্শিত #Tempসংস্করণ এবং নিম্নরূপ দেখায়।

+-----------------+-------------------+---------------------+
|    Operation    |      Context      |    AllocUnitName    |
+-----------------+-------------------+---------------------+
| LOP_BEGIN_XACT  | LCX_NULL          |                     |
| LOP_SHRINK_NOOP | LCX_NULL          |                     |
| LOP_MODIFY_ROW  | LCX_CLUSTERED     | sys.sysschobjs.clst |
| LOP_DELETE_ROWS | LCX_MARK_AS_GHOST | sys.sysschobjs.nc1  |
| LOP_INSERT_ROWS | LCX_INDEX_LEAF    | sys.sysschobjs.nc1  |
| LOP_DELETE_ROWS | LCX_MARK_AS_GHOST | sys.sysschobjs.nc2  |
| LOP_INSERT_ROWS | LCX_INDEX_LEAF    | sys.sysschobjs.nc2  |
| LOP_MODIFY_ROW  | LCX_CLUSTERED     | sys.sysschobjs.clst |
| LOP_COMMIT_XACT | LCX_NULL          |                     |
+-----------------+-------------------+---------------------+

FCheckAndCleanupCachedTempTableলেনদেন উভয় প্রদর্শিত কিন্তু 6 অতিরিক্ত এন্ট্রি হয়েছে #tempসংস্করণ। এটি 6 টি সারি উল্লেখ করছে sys.sysschobjsএবং তাদের উপরে ঠিক একই প্যাটার্ন রয়েছে।

+-----------------+-------------------+----------------------------------------------+
|    Operation    |      Context      |                AllocUnitName                 |
+-----------------+-------------------+----------------------------------------------+
| LOP_BEGIN_XACT  | LCX_NULL          |                                              |
| LOP_DELETE_ROWS | LCX_NONSYS_SPLIT  | dbo.#7240F239.PK__#T________3BD0199374293AAB |
| LOP_HOBT_DELTA  | LCX_NULL          |                                              |
| LOP_HOBT_DELTA  | LCX_NULL          |                                              |
| LOP_MODIFY_ROW  | LCX_CLUSTERED     | sys.sysschobjs.clst                          |
| LOP_DELETE_ROWS | LCX_MARK_AS_GHOST | sys.sysschobjs.nc1                           |
| LOP_INSERT_ROWS | LCX_INDEX_LEAF    | sys.sysschobjs.nc1                           |
| LOP_DELETE_ROWS | LCX_MARK_AS_GHOST | sys.sysschobjs.nc2                           |
| LOP_INSERT_ROWS | LCX_INDEX_LEAF    | sys.sysschobjs.nc2                           |
| LOP_MODIFY_ROW  | LCX_CLUSTERED     | sys.sysschobjs.clst                          |
| LOP_COMMIT_XACT | LCX_NULL          |                                              |
+-----------------+-------------------+----------------------------------------------+

উভয় লেনদেনে এই 6 টি সারি দেখে তারা একই ক্রিয়াকলাপের সাথে মিলে যায়। প্রথমটি কলামটির LOP_MODIFY_ROW, LCX_CLUSTEREDএকটি আপডেট । বাকী পাঁচটি সারি অবজেক্টের নামকরণের সাথে সম্পর্কিত। কারণ ক্ষতিগ্রস্থ এনসিআই ( এবং ) উভয়েরই একটি মূল কলামmodify_datesys.objectsnamenc1nc2 ) এটি মুছে ফেলা / হিসাবে চালিত করা হয় তারপর এটি ক্লাস্টারড সূচীতে ফিরে যায় এবং এটিও আপডেট হয়।

এটি উপস্থিত হয় যে #tempটেবিল সংস্করণটির জন্য যখন সঞ্চিত প্রক্রিয়াটি FCheckAndCleanupCachedTempTableলেনদেনের দ্বারা পরিচালিত পরিচ্ছন্নতার অংশটি শেষ হয় তখন টেম্প টেবিলটির নামকরণ #T__________________________________________________________________________________________________________________00000000E316করা হবে কোনও আলাদা অভ্যন্তরীণ নাম যেমন #2F4A0079এবং যখন CREATE TABLEলেনদেন প্রবেশ করা হয় তখন এটি পুনরায় নামকরণ করে। এই ফ্লিপ ফ্লপিং নামটি অন্য সংযোগের dbo.T2মধ্যে একটি লুপের সাথে সংযোগের মাধ্যমে দেখা যায়

WHILE 1=1
SELECT name, object_id, create_date, modify_date
FROM tempdb.sys.objects 
WHERE name LIKE '#%'

উদাহরণ ফলাফল

স্ক্রিনশট

সুতরাং অ্যালেক্স দ্বারা নির্দেশিত হিসাবে পর্যবেক্ষিত পারফরম্যান্স ডিফারেনশনের জন্য একটি সম্ভাব্য ব্যাখ্যা হ'ল এটি অতিরিক্ত যে কাজটি এটি সিস্টেমের সারণীগুলি বজায় রাখা tempdbদায়বদ্ধ।


উভয় পদ্ধতি একটি লুপে চালিয়ে ভিজ্যুয়াল স্টুডিও কোড প্রোফাইলারটি নিম্নলিখিতটি প্রকাশ করে

+-------------------------------+--------------------+-------+-----------+
|           Function            |    Explanation     | Temp  | Table Var |
+-------------------------------+--------------------+-------+-----------+
| CXStmtDML::XretExecute        | Insert ... Select  | 16.93 | 37.31     |
| CXStmtQuery::ErsqExecuteQuery | Select Max         | 8.77  | 23.19     |
+-------------------------------+--------------------+-------+-----------+
| Total                         |                    | 25.7  | 60.5      |
+-------------------------------+--------------------+-------+-----------+

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

অস্থায়ী সারণী সংস্করণে "অনুপস্থিত" 75% অবদানের জন্য সর্বাধিক গুরুত্বপূর্ণ ফাংশনগুলি

+------------------------------------+-------------------+
|              Function              | Inclusive Samples |
+------------------------------------+-------------------+
| CXStmtCreateTableDDL::XretExecute  | 26.26%            |
| CXStmtDDL::FinishNormalImp         | 4.17%             |
| TmpObject::Release                 | 27.77%            |
+------------------------------------+-------------------+
| Total                              | 58.20%            |
+------------------------------------+-------------------+

ক্রিয়েট এবং রিলিজ উভয় ফাংশনের অধীনে ফাংশনটির CMEDProxyObject::SetNameএকটি অন্তর্ভুক্ত নমুনা মান সহ প্রদর্শিত হয়19.6% । যা থেকে আমি অনুমান করি যে অস্থায়ী টেবিল ক্ষেত্রে 39.2% সময় পূর্বে বর্ণিত পুনর্নবীকরণের সাথে গ্রহণ করা হয়।

এবং অন্যান্য 40% অবদানের ক্ষেত্রে সারণী ভেরিয়েবল সংস্করণে সবচেয়ে বড়গুলি রয়েছে

+-----------------------------------+-------------------+
|             Function              | Inclusive Samples |
+-----------------------------------+-------------------+
| CTableCreate::LCreate             | 7.41%             |
| TmpObject::Release                | 12.87%            |
+-----------------------------------+-------------------+
| Total                             | 20.28%            |
+-----------------------------------+-------------------+

অস্থায়ী সারণী প্রোফাইল

এখানে চিত্র বর্ণনা লিখুন

টেবিলের পরিবর্তনশীল প্রোফাইল

এখানে চিত্র বর্ণনা লিখুন


10

ডিস্কো ইনফার্নো

যেহেতু এটি একটি পুরানো প্রশ্ন, তাই একই কার্য সম্পাদনের প্রোফাইলটি এখনও বিদ্যমান কিনা, বা বৈশিষ্ট্যগুলি আদৌ পরিবর্তিত হয়েছে কিনা তা দেখার জন্য আমি এসকিউএল সার্ভারের নতুন সংস্করণগুলিতে বিষয়টি পুনরায় দেখার সিদ্ধান্ত নিয়েছি।

বিশেষত, এসকিউএল সার্ভার 2019-এ ইন-মেমরি সিস্টেম টেবিলগুলি যুক্ত করা পুনরায় পরীক্ষার জন্য একটি উপযুক্ত উপলক্ষ মনে হয়।

আমি কিছুটা ভিন্ন পরীক্ষার জোতা ব্যবহার করছি, যেহেতু অন্য কোনও বিষয়ে কাজ করার সময় আমি এই সমস্যাটিতে এসেছি।

পরীক্ষা, পরীক্ষা

স্ট্যাক ওভারফ্লোয়ের 2013 সংস্করণ ব্যবহার করে , আমার এই সূচক এবং এই দুটি পদ্ধতি রয়েছে:

সূচক:

CREATE INDEX ix_whatever 
    ON dbo.Posts(OwnerUserId) INCLUDE(Score);
GO

টেম্প টেবিল:

    CREATE OR ALTER PROCEDURE dbo.TempTableTest(@Id INT)
    AS
    BEGIN
    SET NOCOUNT ON;

        CREATE TABLE #t(i INT NOT NULL);
        DECLARE @i INT;

        INSERT #t ( i )
        SELECT p.Score
        FROM dbo.Posts AS p
        WHERE p.OwnerUserId = @Id;

        SELECT @i = AVG(t.i)
        FROM #t AS t;

    END;
    GO 

সারণী পরিবর্তনশীল:

    CREATE OR ALTER PROCEDURE dbo.TableVariableTest(@Id INT)
    AS
    BEGIN
    SET NOCOUNT ON;

        DECLARE @t TABLE (i INT NOT NULL);
        DECLARE @i INT;

        INSERT @t ( i )
        SELECT p.Score
        FROM dbo.Posts AS p
        WHERE p.OwnerUserId = @Id;

        SELECT @i = AVG(t.i)
        FROM @t AS t;

    END;
    GO 

যে কোনও সম্ভাব্য ASYNC_NETWORK_IO অপেক্ষা করার জন্য , আমি মোড়কের পদ্ধতি ব্যবহার করছি।

CREATE PROCEDURE #TT AS
SET NOCOUNT ON;
    DECLARE @i INT = 1;
    DECLARE @StartDate DATETIME2(7) = SYSDATETIME();

    WHILE @i <= 50000
        BEGIN
            EXEC dbo.TempTableTest @Id = @i;
            SET @i += 1;
        END;
    SELECT DATEDIFF(MILLISECOND, @StartDate, SYSDATETIME()) AS [ElapsedTimeMilliseconds];
GO

CREATE PROCEDURE #TV AS
SET NOCOUNT ON;
    DECLARE @i INT = 1;
    DECLARE @StartDate DATETIME2(7) = SYSDATETIME();

    WHILE @i <= 50000
        BEGIN
            EXEC dbo.TableVariableTest @Id = @i;
            SET @i += 1;
        END;
    SELECT DATEDIFF(MILLISECOND, @StartDate, SYSDATETIME()) AS [ElapsedTimeMilliseconds];
GO

এসকিউএল সার্ভার 2017

২০১৪ এবং ২০১ সাল থেকে মূলত এই মুহুর্তে RELICS হ'ল, আমি আমার পরীক্ষাটি ২০১ 2017 এর সাথে শুরু করছি Also এছাড়াও বংশবৃদ্ধির জন্যও আমি পার্ফভিউ সহ কোডটি প্রোফাইলে ডানদিকে ঝাঁপিয়ে পড়েছি । বাস্তব জীবনে আমি ওয়েটস, ল্যাচস, স্পিনলকস, ক্রেজি ট্রেস ফ্ল্যাগস এবং অন্যান্য জিনিসগুলির দিকে নজর রেখেছি।

কোডটি প্রোফাইলিংই হ'ল আগ্রহের কিছু প্রকাশ করে।

সময় পার্থক্য:

  • টেম্প টেবিল: 17891 এমএস
  • টেবিল পরিবর্তনশীল: 5891 এমএস

এখনও খুব স্পষ্ট পার্থক্য, তাই না? তবে এসকিউএল সার্ভার এখন কী আঘাত করছে?

পাগল

বিভক্ত নমুনায় শীর্ষ দুটি বৃদ্ধি দেখে আমরা দেখতে পাচ্ছি sqlminএবং sqlsqllang!TCacheStore<CacheClockAlgorithm>::GetNextUserDataInHashBucketদুটি বৃহত্ অপরাধী।

পাগল

কল স্ট্যাকের নামগুলির দ্বারা বিচার করা, পরিষ্কার করা এবং অভ্যন্তরীণভাবে টেম্প টেবিলগুলির নাম পরিবর্তন করা টেম্প টেবিল কল বনাম টেবিল ভেরিয়েবল কলটির মধ্যে সবচেয়ে বড় সময় বলে মনে হয়।

যদিও টেবিলের ভেরিয়েবলগুলি অভ্যন্তরীণভাবে টেম্প টেবিলগুলি সমর্থন করে, এটি কোনও সমস্যা বলে মনে হয় না।

SET STATISTICS IO ON;
DECLARE @t TABLE(id INT);
SELECT * FROM @t AS t;

সারণী '# B98CE339'। স্ক্যান কাউন্ট 1

সারণী ভেরিয়েবল পরীক্ষার জন্য কল স্ট্যাকের সন্ধান করা মূল অপরাধীদের মধ্যে কোনওটিই প্রদর্শন করে না:

পাগল

এসকিউএল সার্ভার 2019 (ভ্যানিলা)

ঠিক আছে, সুতরাং এটি এখনও এসকিউএল সার্ভার 2017 এ একটি সমস্যা, বাক্সের বাইরে 2019 সালে কিছু আলাদা?

প্রথমত, আমার আস্তিনে কিছুই নেই তা দেখানোর জন্য:

SELECT c.name,
       c.value_in_use,
       c.description
FROM sys.configurations AS c
WHERE c.name = 'tempdb metadata memory-optimized';

পাগল

সময় পার্থক্য:

  • টেম্প টেবিল: 15765 এমএস
  • সারণীর পরিবর্তনশীল: 7250 এমএস

উভয় পদ্ধতি পৃথক ছিল। টেম্প টেবিল কলটি কয়েক সেকেন্ড দ্রুত ছিল এবং টেবিল ভেরিয়েবল কলটি প্রায় 1.5 সেকেন্ড ধীর ছিল। টেবিল ভেরিয়েবল ধীর গতি সারণী ভেরিয়েবল স্থগিত সংকলন দ্বারা আংশিকভাবে ব্যাখ্যা করা যেতে পারে , 2019 সালে একটি নতুন অপ্টিমাইজার পছন্দ।

পারফিউভের ভিন্নতার দিকে তাকালে এটি কিছুটা বদলে গেছে - স্ক্লমিন আর নেই - তবে sqllang!TCacheStore<CacheClockAlgorithm>::GetNextUserDataInHashBucketরয়েছে।

পাগল

এসকিউএল সার্ভার 2019 (ইন-মেমোরি টেম্পডিবি সিস্টেম সারণী)

মেমরি সিস্টেম টেবিল জিনিস এই নতুন সম্পর্কে কি? হুঁ? তার সাথে সুপার?

এটি চালু করা যাক!

EXEC sys.sp_configure @configname = 'advanced', 
                      @configvalue = 1  
RECONFIGURE;

EXEC sys.sp_configure @configname = 'tempdb metadata memory-optimized', 
                      @configvalue = 1 
RECONFIGURE;

নোট করুন যে এটিতে একটি এসকিউএল সার্ভার পুনরায় চালু করতে হবে, তাই এই শুক্রবার বিকেলে এসকিউএল পুনরায় বুট করার সময় আমাকে ক্ষমা করুন।

এখন বিষয়গুলি অন্যরকম দেখাচ্ছে:

SELECT c.name,
       c.value_in_use,
       c.description
FROM sys.configurations AS c
WHERE c.name = 'tempdb metadata memory-optimized';

SELECT *, 
       OBJECT_NAME(object_id) AS object_name, 
       @@VERSION AS sql_server_version
FROM tempdb.sys.memory_optimized_tables_internal_attributes;

পাগল

সময় পার্থক্য:

  • টেম্প টেবিল: 11638 এমএস
  • সারণী ভেরিয়েবল: 7403 এমএস

টেম্প টেবিলগুলি প্রায় 4 সেকেন্ড ভাল করেছে! এইটা একটা জিনিস.

আমি কিছু পছন্দ করি।

এবার পারফভিউ পার্থক্যটি খুব আকর্ষণীয় নয়। পাশাপাশি, বোর্ড জুড়ে সময়গুলি কতটা কাছাকাছি রয়েছে তা আকর্ষণীয়:

পাগল

hkengine!ডিফের একটি আকর্ষণীয় পয়েন্ট হ'ল কলগুলি , যা হেকাটন-ইশ বৈশিষ্ট্যগুলি এখন ব্যবহৃত হচ্ছে বলে মনে হতে পারে seem

পাগল

যতক্ষণ না পার্থক্যের শীর্ষে দুটি আইটেম রয়েছে আমি তেমন কিছু করতে পারি না ntoskrnl!?:

পাগল

বা sqltses!CSqlSortManager_80::GetSortKey, তবে তারা এখানে স্মার্ট পিপিএল-এর জন্য রয়েছে:

পাগল

মনে রাখবেন যে এখানে একটি অননুমোদিত এবং অবশ্যই উত্পাদনের জন্য নিরাপদ নেই তাই দয়া করে এটি স্টার্টআপ ট্রেস পতাকা ব্যবহার করবেন না আপনি মেমোরি বৈশিষ্ট্যে অন্তর্ভুক্ত অতিরিক্ত টেম্প টেবিল সিস্টেম অবজেক্টস (সিস্ট্রোসেটস, সিসলোকুনিটস এবং সিসোবজালুয়েস) ব্যবহার করতে পারেন তবে এটি এক্ষেত্রে মৃত্যুদন্ড কার্যকর করার সময় কোনও উল্লেখযোগ্য পার্থক্য তৈরি করেনি।

পরিক্রমা

এমনকি এসকিউএল সার্ভারের নতুন সংস্করণগুলিতেও টেম্প ভেরিয়েবলগুলিতে উচ্চ ফ্রিকোয়েন্সি কলগুলি টেম্প টেবিলগুলিতে উচ্চ ফ্রিকোয়েন্সি কলগুলির চেয়ে অনেক দ্রুত।

যদিও এটি সংকলন, সংশোধন, অটোর পরিসংখ্যান, ল্যাচস, স্পিনলকস, ক্যাশিং বা অন্যান্য ইস্যুগুলিকে দোষ দিতে লোভনীয়, তবুও বিষয়টি স্পষ্টভাবে টেম্প টেবিল পরিষ্কারের পরিচালনার আশেপাশে রয়েছে।

এটি এসকিউএল সার্ভার 2019-এ মেমোরি সিস্টেমের টেবিলগুলি সক্ষম করে একটি ঘনিষ্ঠ কল, তবে কলের ফ্রিকোয়েন্সি বেশি হলে টেবিলের ভেরিয়েবলগুলি আরও ভাল পারফর্ম করে।

অবশ্যই, একবার ভ্যাপিং ageষি হিসাবে একবার মুশকিল: "পরিকল্পনার পছন্দ কোনও সমস্যা না হলে টেবিল ভেরিয়েবলগুলি ব্যবহার করুন"।


ভাল লাগল - দুঃখিত আমি মিস করেছি যে আপনি আপনার "ডিবাগিং" ব্লগ পোস্টের লিঙ্কটি অনুসরণ না করা অবধি এই উত্তরটির যোগ করেছেন
মার্টিন স্মিথ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.