sql >> データベース >  >> RDS >> Database

互換性レベルとカーディナリティ推定入門書

    はじめに

    1998年から2014年の初めにかけて、SQL Serverは1つのカーディナリティエスティメータ(CE)を使用しましたが、SQL Serverの新しいメジャーバージョン(SQL Server 2008 R2を除く)ごとに新しいデータベース互換性レベルを導入しました。 SQL Serverのネイティブ互換性レベルは、表1の主要なSQLServerバージョンごとに示されています。

    SQLServerのバージョン ネイティブ互換性レベル
    SQL Server 7.0 70
    SQL Server 2000 80
    SQL Server 2005 90
    SQL Server 2008
    SQL Server 2008 R2
    100
    SQL Server 2012 110
    SQL Server 2014 120
    SQL Server 2016 130
    SQL Server 2017 140
    SQL Server 2019 150

    表1:SQLServerのバージョンとネイティブの互換性レベル

    SQLServer7.0とSQLServer2012の間では、データベースの互換性レベルと、そのデータベースのクエリが使用するカーディナリティ推定量との間に関係はありませんでした。これは、1998年にメジャーアップデートを受け取ったカーディナリティエスティメータが1つしかないためです。データベースの互換性レベルは、機能の下位互換性と、SQLServerの新しいバージョンごとにいくつかの新機能を有効/無効にするためにのみ使用されました(これを参照)動作が80から90の間でどのように変化したか、おそらく最も破壊的な変化の例について、StackExchangeが回答します。 SQL Serverデータベースのファイルバージョンとは異なり、データベースの互換性レベルは、簡単なALTER DATABASEコマンドを使用して、サポートされている互換性レベルにいつでも変更できます。

    デフォルトでは、新規を作成した場合 SQL Server 2012のデータベースでは、互換性レベルは110に設定されますが、必要に応じて以前のレベルに変更できます。 復元した場合 SQLServer2008インスタンスからSQLServer2012インスタンスへのデータベースバックアップでは、データベースのファイルバージョンがアップグレードされますが、SQL Server 2008インスタンスでの互換性レベルはそのままになります(80であった場合を除きます。 SQLServer2012でサポートされている最小バージョンである90にアップグレードします。データベースのファイルバージョンとデータベースの互換性レベルの根本的な違いを知っているだけでなく、SQL Server 2014がリリースされる前は、ほとんどのDBAと開発者はデータベースの互換性レベルについてあまり心配する必要はありませんでした。多くの場合、ほとんどのデータベースでは、新しいバージョンのSQLServerへの移行後に互換性レベルが変更されることはありませんでした。最新のデータベース互換性レベルで変更された新しい機能または動作が実際に必要でない限り、これは通常、問題を引き起こしませんでした。

    SQLServer2014の変更

    この古い状況は、SQL Server 2014のリリースによって根本的に変化しました。SQLServer2014では、デフォルトで有効になっている「新しい」カーディナリティ推定器が導入されました。 データベースが120の互換性レベルにあったとき。従来のホワイトペーパー「SQLServer2014Cardinality Estimatorを使用したクエリプランの最適化」で、Joe Sackは、2014年4月にこの変更の背景と動作を説明しています。多くの場合、新しいカーディナリティを使用すると、ほとんどのクエリがより高速に実行されました。推定器ですが、新しいカーディナリティ推定器でパフォーマンスが大幅に低下するクエリに遭遇することはかなり一般的でした。それが起こった場合、SQL Server 2014には、新しいCEによって引き起こされるパフォーマンスの問題を軽減するための多くのオプションがありませんでした。 Joeのホワイトペーパーでは、これらのオプションについて詳しく説明していますが、互換性レベル110以下に戻したい場合を除き、基本的に、クエリオプティマイザが使用するカーディナリティ推定量を制御するためのインスタンスレベルのトレースフラグまたはクエリレベルのクエリヒントに制限されていました。 。

    SQLServer2016の変更

    SQL Server 2016では、データベーススコープの構成オプションが導入されました。これにより、ALTER DATABASE SCOPED CONFIGURATIONコマンドを使用して、以前はインスタンスレベルで構成されていた一部の動作を制御できます。 SQL Server 2016では、これらのオプションには、MAXDOP、LEGACY_CARDINALITY ESTIMATION、PARAMETER_SNIFFING、およびQUERY_OPTIMIZER_HOTFIXESが含まれていました。単一のデータベースのプランキャッシュ全体をクリアできるCLEARPROCEDURE_CACHEオプションもありました。

    このコンテキストで最も関連性があるのは、LEGACY_CARDINALITYESTIMATIONおよびQUERY_OPTIMIZER_HOTFIXESデータベーススコープの構成オプションです。 LEGACY_CARDINALITY ESTIMATIONは、データベースの互換性レベルの設定に関係なく、レガシーCEを有効にします。トレースフラグ9481と同等ですが、インスタンス全体ではなく、問題のデータベースにのみ影響します。これにより、データベースの互換性レベルを130に設定して、機能とパフォーマンスの多くの利点を得ることができますが、データベース全体で従来のCEを使用できます(クエリレベルのクエリヒントで上書きされない限り)。

    QUERY_OPTIMIZER_HOTFIXESオプションは、データベースレベルのトレースフラグ4199と同等です。 SQL Server 2016は、にすべてのクエリオプティマイザのホットパッチを有効にします 130データベース互換性レベルを使用する場合のSQLServer2016 RTM(トレースフラグ4199を有効にしない場合)。 TF 4199を有効にするか、QUERY_OPTIMIZER_HOTFIXESを有効にすると、後にリリースされたすべてのクエリオプティマイザの修正プログラムも取得されます。 SQL Server2016RTM。

    SQL Server 2016 SP1では、以前のQUERYTRACEONクエリヒントよりも使いやすく、理解しやすく、覚えやすいUSEHINTクエリヒントも導入されました。これにより、データベースの互換性レベルと使用されているカーディナリティ推定のバージョンに関連するオプティマイザの動作をさらに細かく制御できます。 sys.dm_exec_valid_use_hintsにクエリを実行して、実行しているSQLServerの正確なビルドの有効なUSEHINT名のリストを取得できます。

    SQLServer2017の変更

    新しい適応クエリ処理機能はSQLServer2017で追加され、データベース互換性レベル140を使用している場合はデフォルトで有効になっています。

    Microsoftは、SQL Serverの新しいメジャーバージョンごとにクエリ最適化に実際に変更と修正が加えられているため、「新しいCE」と「古いCE」という古い用語から離れようとしています。このため、単一の「新しいCE」はもうありません。代わりに、MicrosoftはCE70(SQLServer7.0からSQLServer2012のデフォルトCE)、SQL Server 2014のCE120、SQL Server 2016のCE130、SQL Server 2017のCE140、およびSQLServer2019のCE150を参照したいと考えています。SQLServer以降2017 CU10では、USE HINT機能を使用して、クエリヒントでこれを制御できます。例:

    /*...query...*/ OPTION (USE HINT('QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_130'));

    …特定のクエリに対してCE130カーディナリティ推定量を強制するための有効なクエリヒントになります。

    SQLServer2019の変更

    SQL Server 2019は、データベースが互換モード150を使用している場合にデフォルトで有効になる、さらに多くのパフォーマンスの向上と動作の変更を追加しています。代表的な例は、スカラーUDFインライン化です。もう1つの例は、SQLServer2017の適応クエリ処理のスーパーセットであるインテリジェントクエリ処理機能です。

    表2に示すように、バッチモードを無効にする方法や、アダプティブメモリ付与フィードバックを無効にする方法など、5つの新しいUSEHINTオプションがあります。

    DISABLE_BATCH_MODE_ADAPTIVE_JOINS
    DISABLE_BATCH_MODE_MEMORY_GRANT_FEEDBACK
    DISABLE_INTERLEAVED_EXECUTION_TVF
    DISALLOW_BATCH_MODE
    QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_150

    表2:新しいUSEHINTオプション

    また、16の新しいデータベーススコープ構成オプション(CTP 2.2以降)があり、トレースフラグまたはデータベース互換性レベルの影響も受けるより多くのアイテムをデータベースレベルで制御できます。これにより、データベース互換性レベル150でデフォルトで有効になっている高レベルの変更をよりきめ細かく制御できます。これらを表3に示します。

    ACCELERATED_PLAN_FORCING ELEVATE_RESUMABLE ROW_MODE_MEMORY_GRANT_FEEDBACK
    BATCH_MODE_ADAPTIVE_JOINS GLOBAL_TEMPORARY_TABLE_AUTO_DROP TSQL_SCALAR_UDF_INLINING
    BATCH_MODE_MEMORY_GRANT_FEEDBACK INTERLEAVED_EXECUTION_TVF XTP_PROCEDURE_EXECUTION_STATISTICS
    BATCH_MODE_ON_ROWSTORE ISOLATE_SECURITY_POLICY_CARDINALITY XTP_QUERY_EXECUTION_STATISTICS
    DEFERRED_COMPILATION_TV LIGHTWEIGHT_QUERY_PROFILING
    ELEVATE_ONLINE OPTIMIZE_FOR_AD_HOC_WORKLOADS

    表3:新しいデータベーススコープの構成オプション

    結論

    最新バージョンのSQLServer(つまり、SQL Server 2016以降)への移行は、従来のバージョンのSQLServerよりも大幅に複雑です。さまざまなデータベース互換性レベルとさまざまなカーディナリティ推定バージョンに関連する変更のため、SQL Serverの新しいバージョンで使用するデータベース互換性レベルについて、考え、計画、および実際のテストを行うことが実際には非常に重要です。既存のデータベースをに移行しています。

    Microsoftが推奨するアップグレードプロセスは、最新のSQL Serverバージョンにアップグレードすることですが、ソースデータベースの互換性レベルは維持します。次に、各データベースでクエリストアを有効にし、ワークロードのベースラインデータを収集します。次に、データベースの互換性レベルを最新バージョンに設定し、クエリストアを使用して、最後の既知の適切なプランを強制することにより、パフォーマンスの低下を修正します。

    これがどのように機能し、ワークロードがこれらの変更にどのように反応するかを幸いにも知らない、無計画な「ブラインド」移行を本当に避けたいと考えています。データベースの互換性レベルを適切なバージョンに変更し、適切なデータベーススコープの構成オプションを使用し、絶対に必要な場合は適切なクエリヒントを使用することは、SQLServerの最新バージョンでは非常に重要です。


    1. PostgreSQLの物理レプリケーションメカニズム

    2. Oracleに挿入し、生成されたシーケンスIDを取得する

    3. SQLiteで

    4. Oracleの数値を含む行を返す