web-dev-qa-db-ja.com

大量のPAGELATCH_EX待機を引き起こすマルチステートメントテーブル値関数

マルチステートメントTVFが原因で、非常識なPAGELATCH_EX待機が発生しています。関数によって作成された一時テーブルはtempdbファイル#1にあり、変更されないことがわかりました(常に「#A465FC0D」)。そこに永続的にキャッシュされているようです。この関数は非常に頻繁に使用され、すべてのプロセスが同じ一時テーブルへのアクセスを待機して並んでいます。

この関数は単にstring_splitを実行しますが、string_splitを直接使用するか、関数をインラインTVFに変換するのは7倍遅くなります。分割する文字列は比較的小さいです(最大200 IDですが、多くはほんの数IDです)

CREATE FUNCTION [dbo].[IntListToTable] (@list nvarchar(max))  
RETURNS @intlist TABLE (val int)  
AS  
BEGIN  
  insert into @intlist  
  SELECT  
   CAST(value as int) val  
  FROM  
   string_split(@list, ',')  
  return  
END  

ページラッチはこの関数の使用によって引き起こされることを理解していますが、ここでのキャッシュ/再利用メカニズムをよりよく理解したいと考えています。

この関数は永久に再利用可能になりますか?
そして、これがインラインTVFまたはSTRING_SPLIT()を直接使用するよりも優れているのはなぜですか?

その他の役立つ情報:

  • SQL Server 2017 CU2
  • 24個の一時データベースデータファイルがあります
  • これは、OLTPサーバーよりもワークロードが狭いいくつかの専用読み取りレプリカで発生します。どちらもバッファーキャッシュヒット率が100%で、プランキャッシュヒット率が88%です。
  • インスタンスを再起動すると、新しい一時テーブルが作成され、それ以降も同じです。
1
Jim Clouse

SQL Server 2017 CU2を使用しているため、ヒットしている可能性があります このバグ-SQL Server 2016または2017で激しいtempdb競合が発生します

CU5は上記のバグを修正したため、少なくともCU5に更新します。

CU12(最新)をお勧めします。

3
Kin Shah