প্রতিটি ব্যাচ একটি সংকলন ঘটায়


10

আমাদের একটি তৃতীয় পক্ষের অ্যাপ্লিকেশন রয়েছে যা ব্যাচগুলিতে টি-এসকিউএল বিবৃতি প্রেরণ করে।

ডাটাবেসটি একটি এসকিউএল সার্ভার 2016 এন্টারপ্রাইজ এসপি 1 সিই 7, 16 টি কোর এবং 256 জিবি মেমরিতে হোস্ট করা হয়েছে। অ্যাড-হকের জন্য অনুকূলিতকরণ সক্ষম করা হয়েছে।

এটি যে প্রশ্নগুলি কার্যকর করা হচ্ছে তার একটি চটুল উদাহরণ:

exec sp_executesql N'
IF @@TRANCOUNT = 0 SET TRANSACTION ISOLATION LEVEL SNAPSHOT

select field1, field2 from table1 where field1=@1
option(keep plan, keepfixed, loop join)

select field3, field4 from table2 where field3=@1
option(keep plan, keepfixed, loop join)', N'@1 nvarchar(6)',@1=N'test'

আমি যখন ডাটাবেস নিরীক্ষণ করি এবং আমি ব্যাচ / সেকেন্ড এবং সংকলন / সেকেন্ডের দিকে তাকাই তখন আমি লক্ষ্য করি যে তারা সর্বদা একই থাকে। ভারী বোঝার অধীনে, এটি 1000 ব্যাচ / সেকেন্ড এবং 1000 সংকলন / সেকেন্ড হতে পারে। গড় লোডের অধীনে, এখানে 150 ব্যাচ / সেকেন্ড রয়েছে।

আমি সম্প্রতি সংকলিত পরিকল্পনার জন্য ক্যোয়ারী ক্যাশে বিশ্লেষণ করেছি:

SELECT TOP (1000) qs.creation_time
    , DatabaseName = DB_NAME(st.dbid)
    , qs.execution_count
    , st.text
    , qs.plan_handle
    , qs.sql_handle
    , qs.query_hash 
FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.plan_handle) AS st
ORDER BY creation_time DESC;

আমি যখন ক্যোয়ারীর উপরে চলেছি তখন আমি কেবলমাত্র 10-10 টি নতুন ক্যোয়ারী পরিকল্পনা / সেকেন্ড দেখতে পাই।

এটি প্রতিটি sp_executesqlকল একটি সংকলন ট্রিগার করে তবে কোয়েরিপ্ল্যান ক্যাশে হয় না।

সংকলন / সেকেন্ড সমান ব্যাচ / সেকেন্ড হওয়ার কারণ কী হতে পারে?

উত্তর:


12

এটি প্রতিটি sp_executesqlকল একটি সংকলন ট্রিগার করে তবে কোয়েরি প্ল্যান ক্যাশে হয় না।

এসকিউএল সার্ভার কেবল একটি কলযুক্ত ব্যাচগুলির জন্য কোনও ক্যোয়ারী প্ল্যান ক্যাশে করে নাsp_executesql । কোনও ক্যাশেড পরিকল্পনা ব্যতীত প্রতিবার একটি সংকলন ঘটে। এটি নকশা দ্বারা এবং প্রত্যাশিত।

এসকিউএল সার্ভার সংকলন করতে স্বল্প ব্যয়ের সাথে ক্যাচিং ব্যাচগুলি এড়িয়ে চলে। কী এবং কী করা হয় না তার বিশদ বছরের পর বছরগুলিতে বহুবার পরিবর্তিত হয়েছিল। ট্রেস ফ্ল্যাগের আমার উত্তর 2861 দেখুন এবং বিশদের জন্য 'শূন্য-ব্যয়' পরিকল্পনার আসলে কী অর্থ

সংক্ষেপে, পুনরায় ব্যবহারের সম্ভাবনা (নির্দিষ্ট প্যারামিটার মানগুলি সহ) খুব কম এবং কলযুক্ত অ্যাডহক পাঠ্য সংকলনের জন্য ব্যয় sp_executesqlখুব কম small অভ্যন্তরীণ প্যারামিটারাইজযুক্ত ব্যাচটি উত্পাদিত sp_executesqlঅবশ্যই ক্যাশেড এবং পুনরায় ব্যবহৃত হয় - এটি এর মান। বর্ধিত সঞ্চিত পদ্ধতি sp_executesqlনিজেই ক্যাশে করা হয়।

ক্যাশে এবং পুনরায় ব্যবহার করতে, sp_executesqlবিবৃতিটি বৃহত্তর ব্যাচের অংশ হতে হবে যা ক্যাচিংয়ের জন্য উপযুক্ত বলে মনে করা হয়। উদাহরণ স্বরূপ:

-- Show compilation counter
SELECT
    DOPC.[object_name],
    DOPC.cntr_value
FROM sys.dm_os_performance_counters AS DOPC
WHERE
    DOPC.counter_name = N'SQL Compilations/sec'
GO
-- This is only here to make the batch worth caching
DECLARE @TC integer =
(
    SELECT TOP (1) @@TRANCOUNT 
    FROM master.dbo.spt_values AS SV
);

-- Example call we are testing
-- (use anything for the inner query, this example uses the Stack Overflow database
EXECUTE sys.sp_executesql 
    N'SELECT LT.Type FROM dbo.LinkTypes AS LT WHERE LT.Id = @id;', 
    N'@id int', 
    @id = 1;
GO
-- Show compilation counter again
SELECT
    DOPC.[object_name],
    DOPC.cntr_value
FROM sys.dm_os_performance_counters AS DOPC
WHERE
    DOPC.counter_name = N'SQL Compilations/sec'

এই কোডটি বেশ কয়েকবার চালান। যদিও প্রথমবারে, অনেক সংকলন প্রত্যাশিত হিসাবে রিপোর্ট করা হয়। দ্বিতীয়বার, কোনও সংকলন রিপোর্ট করা হয় না, যদি না optimize for ad hoc workloadsসক্ষম হয় ( তবে কেবল একটি সংকলিত প্ল্যান স্টাব ক্যাশে থাকে)। তৃতীয়বারের মতো, কোনও ক্ষেত্রেই কোনও সংকলনের খবর পাওয়া যায়নি, যেহেতু কোনও স্টাব পুরোপুরি ক্যাশেড অ্যাডহক পরিকল্পনায় প্রচারিত হয়।

সরান DECLARE @TCবিবৃতি দেখতে sys.sp_executesqlবিবৃতি এটা ছাড়া ক্যাশে করা হয় না, নির্বিশেষে বার মৃত্যুদন্ড কার্যকর করা হয় সংখ্যা।

সম্পর্কিত প্ল্যান ক্যাশে এন্ট্রিগুলি এর সাথে দেখুন:

-- Show cached plans
SELECT
    DECP.refcounts,
    DECP.usecounts,
    DECP.size_in_bytes,
    DECP.cacheobjtype,
    DECP.objtype,
    DECP.plan_handle,
    DECP.parent_plan_handle,
    DEST.[text]
FROM sys.dm_exec_cached_plans AS DECP
CROSS APPLY sys.dm_exec_sql_text(DECP.plan_handle) AS DEST
WHERE 
    DEST.[text] LIKE N'%sp_executesql%'
    AND DEST.[text] NOT LIKE N'%dm_exec_cached_plans%';

সম্পর্কিত প্রশ্নোত্তর: ট্রিগারগুলি কি প্রতিবার সংকলন করে?


11

আপনি অনুমান করতে পারে কি আপনার জন্য পারফরমেন্স মনিটর এবং কার্যকলাপ মনিটর মধ্যে দেখতে SQL Compilations/secএবং Batch Requests/secএকটি পরীক্ষা হিসেবে পৃথক ক্যোয়ারী উইন্ডোতে কিছু ব্যাচ চালানোর সময়, নিচের বিস্তারিত।

প্রশ্ন উইন্ডো 1:

DECLARE @t1 datetime;
DECLARE @t2 datetime;
DECLARE @CompVal1 int;
DECLARE @CompVal2 int;
DECLARE @ReCompVal1 int;
DECLARE @ReCompVal2 int;
DECLARE @BatchVal1 int;
DECLARE @BatchVal2 int;
DECLARE @ElapsedMS decimal(10,2);

SELECT @t1 = GETDATE()
    , @CompVal1 = (
        SELECT spi.cntr_value
        FROM sys.sysperfinfo spi
        WHERE spi.counter_name = 'SQL Compilations/sec                                                                                                            '
        )
    , @ReCompVal1 = (
        SELECT spi.cntr_value
        FROM sys.sysperfinfo spi
        WHERE spi.counter_name = 'SQL Re-Compilations/sec                                                                                                         '
        )
    , @BatchVal1 = (
        SELECT spi.cntr_value
        FROM sys.sysperfinfo spi
        WHERE spi.counter_name = 'Batch Requests/sec                                                                                                              '
        );

WAITFOR DELAY '00:00:10.000';

SELECT @t2 = GETDATE()
    , @CompVal2 = (
        SELECT spi.cntr_value
        FROM sys.sysperfinfo spi
        WHERE spi.counter_name = 'SQL Compilations/sec                                                                                                            '
        )
    , @ReCompVal2 = (
        SELECT spi.cntr_value
        FROM sys.sysperfinfo spi
        WHERE spi.counter_name = 'SQL Re-Compilations/sec                                                                                                         '
        )
    , @BatchVal2 = (
        SELECT spi.cntr_value
        FROM sys.sysperfinfo spi
        WHERE spi.counter_name = 'Batch Requests/sec                                                                                                              '
        );

SET @ElapsedMS = DATEDIFF(MILLISECOND, @t1, @t2);
SELECT  ElapsedTimeMS = @ElapsedMS
    , [SQL Compilations/sec] = (@CompVal2 - @CompVal1) / @ElapsedMS * 1000 
    , [SQL Recompilations/sec] = (@ReCompVal2 - @ReCompVal1) / @ElapsedMS * 1000
    , [Batch Requests/sec] = (@BatchVal2 - @BatchVal1) / @ElapsedMS * 1000;

প্রশ্নের উইন্ডো 2-তে, উপরের কোডটি চলমান অবস্থায় নিম্নলিখিতটি চালান। কোডটি কেবল 100 টি-এসকিউএল ব্যাচ চালায়:

EXEC sys.sp_executesql N'SELECT TOP(1) o.name FROM sys.objects o;';
GO 100

আপনি যদি ক্যোরি উইন্ডো 1 এ ফিরে যান তবে আপনি এরকম কিছু দেখতে পাবেন:

╔═══════════════╦══════════════════════╦══════════ ══════════════╦════════════════════╗
La বিভক্ত সময়সীমা ║ এসকিউএল সংকলন / সেকেন্ড ║ এসকিউএল পুনঃসংকলন / সেকেন্ড ║ ব্যাচের অনুরোধ / সেকেন্ড ║
╠═══════════════╬══════════════════════╬══════════ ══════════════╬════════════════════╣
20 10020.00 ║ 10.07984031000 ║ 0.00000000000 ║ 10.07984031000 ║
╚═══════════════╩══════════════════════╩══════════ ══════════════╩════════════════════╝

আমরা যদি এই কোয়েরিটি তাকান:

SELECT dest.text
    , deqs.execution_count
FROM sys.dm_exec_query_stats deqs
    CROSS APPLY sys.dm_exec_sql_text(deqs.plan_handle) dest
WHERE dest.text LIKE 'SELECT TOP(1)%'

আমরা নিশ্চিত করতে পারি যে পরীক্ষার ক্যোয়ারির 100 টি মৃত্যুদণ্ড কার্যকর হয়েছিল।

উপরে ফলাফল, আপনি আমরা সংকলন পেয়ে থাকেন দেখতে পারেন প্রতিটি সময়sp_executesql বিবৃতি সঞ্চালন করে। এর জন্য পরিকল্পনা অবশ্যই ক্যাশে হচ্ছে, তবুও আমরা এর জন্য একটি সংকলন দেখছি; কি দেয়?

মাইক্রোসফট ডক্স বিষয়ে এই কথা sp_executesql:

sp_executesql এর ব্যাচ, নামগুলির ক্ষেত্র এবং ডেটাবেস প্রসঙ্গে প্রসঙ্গে EXECUTE এর মতোই আচরণ রয়েছে। Sp_executesql @stmt প্যারামিটারে লেনদেন-এসকিউএল স্টেটমেন্ট বা ব্যাচটি sp_executesql স্টেটমেন্ট কার্যকর না হওয়া পর্যন্ত সংকলিত হয় না। @Stmt এর বিষয়বস্তুগুলি তখন sp_executesql নামক ব্যাচের এক্সিকিউশন পরিকল্পনার থেকে পৃথক করে একটি এক্সিকিউশন প্ল্যান হিসাবে নির্বাহ করা হয় এবং কার্যকর করা হয়।

সুতরাং, কমান্ড পাঠ্যের জন্য পরিকল্পনা ইতিমধ্যে পরিকল্পনা ক্যাশে থাকা সত্ত্বেও প্রতিটি সময় এটি চালিত হওয়ার সাথে সাথে sp_executesql নিজেই সংকলন করা হচ্ছে। @ পালওহাইট তার উত্তরে দেখায় যে sp_executesql- এ সর্বাধিক কলগুলি বাস্তবে ক্যাশে হয় না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.