web-dev-qa-db-ja.com

ストアドプロシージャのMicrosoft SQL Server 2016パフォーマンスの低下が数千回と呼ばれる

コンテキスト:

小さなテーブル、テーブルを更新するストアドプロシージャ、最初の2000ヒットは問題ありません。それらの最初のヒットの後、それはカタツムリのペースに這い始めます。このストアドプロシージャは、呼び出し元のC#アプリを使用するSQL Server 2008 R2の現在の環境では問題ありません。 SQL Server 2016の新しいテスト環境では、この問題が発生しています。クエリの問題のあるセクションは、小さいテーブルの更新のparamと等しくない列の4つの比較を持つwhere句を扱います。

WHERE A.Column1 <> @param1 OR A.Column2 <> @param2     etc..

私の仮定はパラメータスニッフィングでしたが、さまざまなクエリヒントでそれを除外しました。

私も試しました:

  • 更新しない選択に変更
  • 並列度(MAXDOP)で遊ぶ
  • 統計の更新と再コンパイル、プロセスの途中であっても
  • インデックスへのさまざまな変更
  • X回の反復後のC#コードの呼び出しでの接続プールのリセット
  • トランザクションコントロールの削除

問題を改善しているように見える唯一の変更は、where句を削除してロジックをセッターにプッシュすることです。

SET A.Column1 = CASE 
        WHEN A.Column1 <> @param1
            THEN @param1
        ELSE A.Column1
        END

コードを変更する必要はありませんが、SQL Server 2016が機能しなくなる理由を解決できる他のリソースをオンラインで見つけられませんでした。

任意の助けいただければ幸いです。

4
acg

SQL Server 2014以降では、新しいカーディナリティ推定ロジックが導入されました。

BOLから:

基数推定ロジックと呼ばれる基数推定ロジックは、SQL Server 2014で再設計されて、クエリプランの品質が向上し、クエリのパフォーマンスが向上しています。新しいカーディナリティエスティメータは、現代のOLTPおよびデータウェアハウジングのワークロードで適切に機能する仮定とアルゴリズムを組み込んでいます。これは、現代のワークロードに関する詳細なカーディナリティ推定調査と過去15年間の私たちの学習に基づいています。 SQL Serverのカーディナリティエスティメータを改善することの結果です。顧客からのフィードバックによると、ほとんどのクエリは変更から恩恵を受けるか、変更されないままですが、小さい数は以前のカーディナリティエスティメータと比較して回帰を示す可能性があります

最近、SQL Server 2012からSQL Server 2014にアップグレードし、新しいCardinality Estimatorが間もなく登場しました-クエリがタイムアウトし、CPUが100%近くに達しました。

多くのトラブルシューティング、統計の更新、インデックスの再構築、クエリプラン分析を行った結果、互換性レベルをSQL 2012に変更するとうまくいくことがわかりました。

ポールホワイトは次のように説明します- 複数の述語のカーディナリティ推定

データベースの互換性レベルが120未満に設定されている場合、またはトレースフラグ9481がアクティブな場合、SQL Server 2014の選択性計算は以前のバージョンと同じように動作します(そしてトレースフラグ4137は以前と同様に機能します)。

だから私のアドバイスは

  • 問題を明らかにするクエリの数が少ない場合は、QUERYTRACEON(9481)ヒントを使用します。
  • ギャンブルしたくない場合は、トレースフラグTF9481を起動パラメータとして指定するだけで、サーバーの再起動中も保持されます。

注:TF 9481を有効にすると、データベースの互換性レベルを低いレベルに設定する必要がなくなります。

から KB280141

9481:デフォルトのデータベース互換性レベル120でSQL Server 2014を実行するときに使用します。トレースフラグ9481は、クエリオプティマイザーがクエリプランを作成するときにカーディナリティエスティメーターのバージョン70(SQL Server 2012バージョン)を使用するように強制します。

補足として、適切なテストとともに、TF4199も調べてください(クエリオプティマイザーのすべての修正を有効にするマスターキーとして考えてください)。 TF4199の動作はSQL Server 2016で変更されます。 。 TF4199は私の環境で大いに役立ち、すべての新しいインストールでデフォルトでオンになっています。

SQL Server 2016では、トレースフラグ9481をオンにする必要はありません。

SELECT  name, value  
    FROM  sys.database_scoped_configurations  
    WHERE name = 'LEGACY_CARDINALITY_ESTIMATION'; 
-- if above is having value = 0, then set to ON
ALTER DATABASE
    SCOPED CONFIGURATION  
        SET LEGACY_CARDINALITY_ESTIMATION = ON;  
go  

トレースフラグ4199の場合、次のことができます

ALTER DATABASE
    SCOPED CONFIGURATION  
        SET QUERY_OPTIMIZER_HOTFIXES = ON
5
Kin Shah