[SQL SERVER]SQL2016-新查詢提示 for Memory

SLQ Server 2016新增兩個查詢提示MIN_GRANT_PERCENT 和MAX_GRANT_PERCENT,

設定值介於0~100.0之間。

SQL Server針對查詢進行compile過程中,會估算需要多少記憶體,

但這機制僅適用動態查詢,對於快取中的計畫並不適用,

這是因為SQL Server只會針對快取計畫的第一次執行參數進行記憶體估算,

而這也是導致發生記憶體低估或高估的效能問題主因。

一般我們最常見需要記憶體分配的運算子如Sort、Hash join(aggregation、union),

不管是低估Sort或高低Hash都會造成巨大效能問題。

針對記憶體授權問題,你現在有更快方式修正,就是透過MIN_GRANT_PERCENT and MAX_GRANT_PERCENT這兩個查詢提示,

好消息是,這兩個查詢提示也已經套用在SQL2012 SP3以後版本(有使用SQL2012版本的朋友,建議升級SP3,因為不只是修正Bug,更包含一系列效能調整相關功能)。

Memory Grant提示有點像微型記憶體資源管理員(resource governor),

可以讓你針對個別查詢限制記憶體最大和最小使用量,如果指定值小於執行查詢所需記憶體總量,

該查詢依然會要求總記憶體量,並不用擔心會發生執行查詢錯誤情況,下面我簡單重現記憶體授權效能問題。

create proc USP_testMemory
(@c2 varchar(40))
as
set nocount on
select c1,c2,c3,c4 
from dbo.TestLike 
where c2=@c2
order by c3

--第一次執行參數 FeiFei
exec USP_testMemory 'FeiFei'

可以看到雖然只有一筆資料,但依照預設記憶體查詢設定,最少也需要1024 kb的記憶體授權。

 

--第二次執行參數 this isnot possible
exec USP_testMemory 'this isnot possible'

這次返回78033筆資料,但記憶體授權卻還是1024KB,低估記憶體授權,

導致排序運算子使用tempdb資源,解決這效能問題的方法很多,

但這裡我示範使用MIN_GRANT_PERCENT來解決。

alter proc USP_testMemory
(@c2 varchar(40))
as
set nocount on
select c1,c2,c3,c4 
from dbo.TestLike 
where c2=@c2
order by c3
option(MIN_GRANT_PERCENT=1.5)--表示我們將使用更多記憶體

--第二次執行參數 this isnot possible
exec USP_testMemory 'this isnot possible'

雖然因為cache plan影響估計的資料列數目,我們使用提示告訴SQL SERVER將使用更多記憶體,

讓原本執行時間快了200ms,但要注意並行查詢記憶體競爭問題。

 

Enjoy SQL Server 2016

 

參考

What's New in Database Engine

New memory grant query hint MIN_GRANT_PERCENT came to rescue

Query Hints (Transact-SQL)

The case of the columnstore index and the memory grant

[SQL SERVER][Memo]了解參數探測行為(1)
[SQL SERVER][Memo]了解參數探測行為(2)
[SQL SERVER]SQL2016-資料庫範圍組態選項