অত্যধিক সাজানোর মেমরি অনুদান


45

এই সাধারণ জিজ্ঞাসা এত মেমরি কেন দেওয়া হয়?

-- Demo table
CREATE TABLE dbo.Test
(
    TID integer IDENTITY NOT NULL,
    FilterMe integer NOT NULL,
    SortMe integer NOT NULL,
    Unused nvarchar(max) NULL,

    CONSTRAINT PK_dbo_Test_TID
    PRIMARY KEY CLUSTERED (TID)
);
GO
-- 100,000 example rows
INSERT dbo.Test WITH (TABLOCKX)
    (FilterMe, SortMe)
SELECT TOP (100 * 1000)
    CHECKSUM(NEWID()) % 1000,
    CHECKSUM(NEWID())
FROM sys.all_columns AS AC1
CROSS JOIN sys.all_columns AS AC2;
GO    
-- Query
SELECT
    T.TID,
    T.FilterMe,
    T.SortMe,
    T.Unused
FROM dbo.Test AS T 
WHERE 
    T.FilterMe = 567
ORDER BY 
    T.SortMe;

আনুমানিক ৫০ টি সারির জন্য, এই অপ্টিমাইজারটি বাছাইয়ের জন্য প্রায় 500 এমবি সংরক্ষণ করে:

আনুমানিক পরিকল্পনা

উত্তর:


42

এটি এসকিউএল সার্ভারে একটি বাগ (২০০৮ থেকে ২০১৪ পর্যন্ত অন্তর্ভুক্ত)।

আমার বাগ রিপোর্ট এখানে

ফিল্টারিং শর্তটি স্ক্যান অপারেটরে একটি অবশিষ্টাংশ হিসাবে বিবেচিত হয়, তবে বাছাইয়ের জন্য মেমরিটি ভুলভাবে গণনা করা হয় ফিল্টার প্রাক কার্ডিনালিটির প্রাক্কলনের ভিত্তিতে ।

ইস্যুটি চিত্রিত করার জন্য, ফিল্টারটিকে স্ক্যান অপারেটরটিতে নামানো থেকে রোধ করতে আমরা (অননুমোদিত এবং অসমর্থিত) ট্রেস পতাকা 9130 ব্যবহার করতে পারি । বাছাই করা মেমরিটি এখন সঠিকভাবে ফিল্টার আউটপুটের আনুমানিক কার্ডিনালিটির উপর ভিত্তি করে স্ক্যান নয়:

SELECT
    T.TID,
    T.FilterMe,
    T.SortMe,
    T.Unused
FROM dbo.Test AS T 
WHERE 
    T.FilterMe = 567
ORDER BY 
    T.SortMe
OPTION (QUERYTRACEON 9130); -- Not for production systems!

আনুমানিক পরিকল্পনা

একটি উত্পাদন ব্যবস্থার জন্য , সমস্যাযুক্ত পরিকল্পনার আকারটি এড়াতে পদক্ষেপগুলি নেওয়া প্রয়োজন (অন্য কলামে একটি ছাঁকনি দিয়ে ছাঁকানো ফিল্টার)। এটি করার একটি উপায় হ'ল ফিল্টার শর্তে একটি সূচক সরবরাহ করা এবং / অথবা প্রয়োজনীয় সাজানোর ক্রম সরবরাহ করা।

-- Index on the filter condition only
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe
ON dbo.Test (FilterMe);

এই সূচিটি স্থিতিতে , বাছাইয়ের জন্য পছন্দসই মেমরি অনুদানটি কেবল 928 কেবি :

ফিল্টার সূচক সহ

আরও এগিয়ে গেলে, নিম্নলিখিত সূচকটি সম্পূর্ণরূপে বাছাই করতে পারে ( শূন্য মেমরি অনুদান):

-- Provides filtering and sort order
-- nvarchar(max) column deliberately not INCLUDEd
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe_SortMe
ON dbo.Test (FilterMe, SortMe);

ফিল্টার এবং সাজানোর সূচক সহ

এসকিউএল সার্ভার x64 বিকাশকারী সংস্করণের নিম্নলিখিত বিল্ডগুলিতে পরীক্ষিত এবং বাগটি নিশ্চিত হয়েছে:

2014   : 12.00.2430 (RTM CU4)
2012   : 11.00.5556 (SP2 CU3)
2008R2 : 10.50.6000 (SP3)
2008   : 10.00.6000 (SP4)

ছিল ফিক্সড মধ্যে SQL সার্ভার 2016 সার্ভিস প্যাক 1 । প্রকাশের নোটগুলিতে নিম্নলিখিতগুলি অন্তর্ভুক্ত রয়েছে:

ভিএসটিএস বাগ নম্বর 8024987
টেবিল স্ক্যান এবং ইনডেক্স স্ক্যানগুলি পুশ ডাউন প্রিকেট সহ প্যারেন্ট অপারেটরের জন্য মেমরি অনুদানকে ছাড়িয়ে যায়।

পরীক্ষিত এবং নিশ্চিত হওয়াটির উপর স্থির:

  • Microsoft SQL Server 2016 (SP1) - 13.0.4001.0 (X64) Developer Edition
  • Microsoft SQL Server 2014 (SP2-CU3) 12.0.5538.0 (X64) Developer Edition

সিই মডেল উভয়ই।


5

এসকিউএল ২০১২ থেকে আপনি এবং এর মধ্যে একটি বৃহত তাত্পর্য খুঁজে পেতে পারেন , যেমন এর মতো কিছু:SerialRequiredMemorySerialDesiredMemory

-- Search plan cache for Memory Grant issues
IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp

-- Collect more info about the plan here if required, eg usecounts, objtype etc, 
SELECT IDENTITY( INT, 1, 1 ) rowId, query_plan
INTO #tmp
FROM sys.dm_exec_cached_plans cp WITH(NOLOCK)
    CROSS APPLY sys.dm_exec_query_plan(plan_handle)
GO


;WITH cte AS
(
SELECT
    rowId,
    query_plan,
    m.c.value ('@SerialRequiredMemory', 'INT' ) AS SerialRequiredMemory,
    m.c.value ('@SerialDesiredMemory', 'INT' ) AS SerialDesiredMemory

FROM #tmp t
    CROSS APPLY t.query_plan.nodes ( '//*:MemoryGrantInfo[@SerialDesiredMemory[. > 0]]' ) m(c)
), cte2 AS (
SELECT *,
    CAST( CAST( SerialDesiredMemory AS DECIMAL(10,2) ) / CAST( SerialRequiredMemory AS DECIMAL(10,2) ) AS DECIMAL(10,2) ) Desired_to_Required_ratio
FROM cte
)
SELECT TOP 20
    rowId,
    query_plan,
    SerialRequiredMemory SerialRequiredMemory_KB,
    SerialDesiredMemory SerialDesiredMemory_KB,
    CAST( SerialRequiredMemory / 1024. AS DECIMAL(10,2) ) SerialRequiredMemory_MB,
    CAST( SerialDesiredMemory / 1024. AS DECIMAL(10,2) ) SerialDesiredMemory_MB,
    Desired_to_Required_ratio
FROM cte2
WHERE Desired_to_Required_ratio > 100
ORDER BY Desired_to_Required_ratio DESC

এই নতুন বৈশিষ্ট্য সম্পর্কে আরও কিছু নোট এখানে । এই ক্যোয়ারীটি কিছুটা রুক্ষ এবং প্রস্তুত তবে আমার এসকিউএল সার্ভার 2014 ডি বক্স থেকে 975.47 অনুপাতের সাথে আরও কয়েকটি চোখের পপিংয়ের পরিকল্পনা নিয়ে অতিরিক্ত ক্রম অনুসন্ধানটি গ্রহণ করেছে। 'স্বাভাবিক' অনুপাত (কমপক্ষে আমার সীমাবদ্ধ পরীক্ষা থেকে) ~ 1 বলে মনে হয়।

আছে HTH


3

সব ধরনের সাহায্য করার জন্য ধন্যবাদ। আমি ভেবেছিলাম যে আমরা উপরের ক্যোয়ারীর একটি আপডেট সংস্করণ পাঠাব যা আমরা সহায়ক বলেছি।

-- Search plan cache for Memory Grant issues
IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp

-- Collect more info about the plan here if required, eg usecounts, objtype etc, 
SELECT IDENTITY( INT, 1, 1 ) rowId, query_plan, db = DB_NAME(CAST(pa.value AS int))
INTO #tmp
FROM sys.dm_exec_cached_plans cp WITH(NOLOCK)
    CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle)
    OUTER APPLY sys.dm_exec_plan_attributes(cp.plan_handle) pa 
    WHERE pa.attribute = 'dbid' 
GO

;WITH cte AS
(
SELECT
    rowId,
    query_plan,
    m.c.value ('@SerialRequiredMemory', 'INT' ) AS SerialRequiredMemory,
    m.c.value ('@SerialDesiredMemory', 'INT' ) AS SerialDesiredMemory,
    db
FROM #tmp t
    CROSS APPLY t.query_plan.nodes ( '//*:MemoryGrantInfo[@SerialDesiredMemory[. > 0]]' ) m(c)
), cte2 AS (
SELECT *,
    CAST( CAST( SerialDesiredMemory AS DECIMAL(10,2) ) / CAST( SerialRequiredMemory AS DECIMAL(10,2) ) AS DECIMAL(10,2) ) Desired_to_Required_ratio
FROM cte
)
SELECT TOP 20
    rowId,
    query_plan,
    SerialRequiredMemory SerialRequiredMemory_KB,
    SerialDesiredMemory SerialDesiredMemory_KB,
    CAST( SerialRequiredMemory / 1024. AS DECIMAL(10,2) ) SerialRequiredMemory_MB,
    CAST( SerialDesiredMemory / 1024. AS DECIMAL(10,2) ) SerialDesiredMemory_MB,
    Desired_to_Required_ratio,
    db
FROM cte2
WHERE Desired_to_Required_ratio > 100
ORDER BY Desired_to_Required_ratio DESC
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.