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

パラメータスニッフィングウェビナーシリーズのQ&A

    過去2回の水曜日に、パラメータ感度の問題を扱う2部構成のウェビナーシリーズを開催しました:

    • ストアドプロシージャ、パラメータ、問題…
      キンバリー・L・トリップとアーロン・ベルトラン
      1月24日
      見逃しましたか?今すぐ視聴するために登録してください!

    • SentryOneを使用したパラメータスニッフィングへの取り組み
      アーロン・ベルトラン、キンバリー・L・トリップ、アンディ・マロン
      1月31日
      見逃しましたか?今すぐご覧ください!

    両方のウェビナーでいくつかの質問が出てきたので、それらをまとめてここで回答すると思いました(回答の一部はウェビナーでAndyから寄せられました)。

    最近見た問題では、計画がすぐにキャッシュから削除されるのを目にしています。あなたが説明することは何も実行していません( DBCC FREEPROCCACHE 等。);記憶圧もこれを引き起こす可能性がありますか?

    はい、メモリの負荷が要因になる可能性があり(この投稿を参照)、この点に関してもSQLServerのメモリ管理に関する潜在的な問題について調査が行われていることを私は知っています。

    出席者から:「質問ではありませんが、プランキャッシュが空になる回数について尋ねるユーザーへのコメントです。これもありましたが、実際にはメモリの負荷でした。サーバーの最大メモリが正しく構成されていませんでした。ここで説明した式を使用して修正した後、この記事の手順を10分ごとに実行しました(動的SQLが大量にあり、1回だけ使用しました)。 "

    またはを使用するとどうなりますか ANDの代わりにwhere句で 、問題は解決しませんか?

    通常、 ORを使用する場合 このタイプのパターンでは、すべてのパラメーターに行をフィルター処理する値が入力されていない限り、毎回すべての行を取得します。これにより、クエリのセマンティクスが「これらすべてが真である必要がある」から「これらのいずれかが真である可能性がある」に変更されます。それでも、パラメータの最初のセット用にコンパイルされたプランは、句が AND を使用しているかどうかに関係なく、キャッシュされ、将来の実行のために保持されます。 またはまたは

    それは1=1 ですか 良いアプローチにフラグを立てますか?提供されているパラメーターのみを追加して、醜い 1 =1を回避することをお勧めします。 ?

    1 =1 SQL Serverでは事実上無視されますが、すべての条件節を ANDで追加できます。 そのため、*最初の*ものを別の方法で扱う必要はありません。代替案は次のとおりです:

    SET @IncludedWhereClauseYet bit = 0;
    SET @sql = N'SELECT cols FROM dbo.Table';
     
    IF @param1 IS NOT NULL
    BEGIN
      IF @IncludedWhereClauseYet = 0
      BEGIN
        SET @sql += N' WHERE ';
        SET @IncludedWhereClauseYet = 1;
      END
      ELSE
      BEGIN
        SET @sql += N' AND ';
      END
      SET @sql += N' @param1 = @param1';
    END
     
    IF @param2 IS NOT NULL
    BEGIN
      IF @IncludedWhereClauseYet = 0
      ...
    END
    ...

    1 =1 句の前に常にANDを付けることで、簡略化できます 。上記のコードは次のようになります:

    SET @sql = N'SELECT cols FROM dbo.Table WHERE 1 = 1';
     
    IF @param1 IS NOT NULL
    BEGIN
      SET @sql += N' AND @param1 = @param1';
    END
     
    IF @param2 IS NOT NULL
    BEGIN
      SET @sql += N' AND @param2 = @param2';
    END

    WHERE PrimaryKey> 0 のように、別の初期句を使用してすべての条件を回避することもできます。 またはWHEREPrimaryKey IS NOT NULL 、その後のすべての句は ANDで始まる可能性があります 。ただし、 1 =1 、醜いですが、無害であり、IMHOは、*本物の*句が計画に影響を与える可能性があることを除いて、*本物の*が無意味な句を追加するのと同じくらい醜いです。

    T-SQLを使用してT-SQLコードを作成する場合、「醜い」という2つの側面について考える必要があります。上記のコードのトラブルシューティングを行う場合と、から出てくるクエリのトラブルシューティングを行う場合があります。それ。もう一方のために一方を犠牲にすることに注意してください。

    何?!私はそれを完全に見逃しました…WITHRECOMPILE 。私はそれが計画を空にしたと思いました、しかしそれはこの実行のためだけにそれを残します…それは知ることは非常に重要です!

    欠点にも注意してください。
    PaulWhiteによるこのすばらしい投稿をご覧ください。

    OPTION OPTIMIZE FOR @parametername UNKNOWN 最近のSQLバージョンでは推奨されなくなりましたか?

    最新バージョンでは、SQL Server 2008で最初に導入されたときよりも良くも悪くもないと思います。私が知る限り、オプティマイザーとカーディナリティ推定器にすべての変更を加えても、そのビットは同じように動作します。

    SentryOneでプロシージャ統計とクエリ統計のキャプチャを有効にした場合、サーバーに負荷はありますか?

    Procedure&Querystatsコレクションはデフォルトでオンになっているはずです。すべてのデータ収集にはコストが伴いますが、SQL Sentryは、収集によって発生するコストに細心の注意を払っています。

    RSのシークは、それを残りの述語として使用していませんでした。私が見ることができなかった他の何かをシークしていました。

    おかげで、私はその例を再検討し、デモについて個別にブログを書き、計画図だけでは明らかではなかった関連する詳細を含めるようにします。

    INCLUDEとして必要な列のいくつかを追加するのは本当ではありませんか ■キールックアップが削除されないため、実際にはインデックスがより効果的になりませんか?実際にキールックアップを削除しない限り、パーセンテージは変わらないはずだと思います。

    厳密に言えば、そうです。元のクエリは、 SELECT *を使用した最も悪い例でした。 そして、絶望的な数の列が欠落しているインデックス。私が言いたかったのは、[インデックス分析]タブでは、(a)クエリを改善し、(b)インデックスをカバーするように勧めているということです。スコアは、どちらかまたは両方を実行するように誘導するためにあります。クエリを変更して必要な列を少なくすると、インデックスもクエリをカバーするようになります。新しい個別のカバーするインデックスを作成する場合は、この特定のクエリをカバーするために必要な列に関する情報もあります。技術的には、その通りです。1つのインクルード列を追加しても、他の4つの列を検索する必要がある場合でも、この特定のクエリのパフォーマンスは向上せず、インデックスも向上しませんが、それはあなたが近づいています。インクルード列を1つ追加するだけでなく、残りを無視することをお勧めします。いつ停止するかわからないので、完璧な解決策があるかどうかはわかりません。落胆したくないのは確かです。 ユーザーが自分のインデックスをクエリにより適したものにすることから。

    名のパラメーターのみを使用するステートメントの下に要約された名のパラメーターと名のパラメーターを使用するクエリが表示されるのはなぜですか?

    更新: これは意図的なものです。 [合計の表示]の下のグループ化は、さまざまなパラメーターの組み合わせすべてで呼び出された同じ手順をグループ化します。したがって、最初にそれを使用して、パフォーマンスが最も低くなる傾向があるパラメーターを判別し、その中で、データの偏りがあるかどうかをドリルインできます。たとえば、インデックス付けされていない列に対する検索につながるパラメータは、おそらくかなり確実に一番上にバブルアップします。渡された他のパラメータと組み合わせて、そのパラメータがなかったすべての呼び出しと比較されていることがわかります。合格しました。

    以上のことをすべて述べた上で、現在実行中のトップSQL画面の変更を完了する際に、このグループ化の動作を微調整することを検討します。

    プランガイドの使用方法に関するドキュメントはありますか?私は現在、それを行う方法がわかりません。

    これは私がブログで取り上げるつもりだった他のことですが、Microsoftはその間にいくつかのトピックをここに持っています(そしてサイドバーのすべての関連リンクをチェックしてください)。

    クエリ履歴チャートを取得するには、何かを有効にする必要がありますか?

    いいえ、これはSentryOneクライアントアプリケーションのすべての最新バージョンで有効にする必要があります。表示されない場合は、ツール>レイアウトのリセットを試してください。;それでも問題が解決しない場合は、[email protected]にお問い合わせください。

    計画の回帰が悪い考えであることが判明したときに、クエリストアを使用して最後の既知の良い計画を強制する場合はありますか?あなたが示したようにステートメントを変更することで、より適切に対処される問題を隠す傾向がありますか?

    計画を強制することは、多くの場合、最後の手段の種類のオプションであり、私は、あなたが本当に、本当に、本当に本当にステートメントを修正できない(またはインデックスを変更できない)場合のためにそれを予約する傾向があります。計画を強制すると、常に間違った行動につながる可能性があります。それはまだ人間がその選択をしているためであり、悪い情報に基づいて計画を立てている可能性があります。回帰は計画の変更が原因である可能性がありますが、実行時間が長かったために回帰と判断した場合、他の考えられる理由を調査しましたか?たとえば、システムが再起動されたか、フェイルオーバーが発生し、古いプランが削除されたために新しいプランを取得し、その間に統計も変更されたとしますが、プランが悪いためではなく、クエリの実行時間が長くなります。むしろ、バッファが空だったからです。そうです、私は確かにすべての回帰に計画を強制することを提案しません。

    SentryOneは常にデータやパラメーターをキャプチャしているわけではないので、十分な情報がありません。 SentryOneがパラメータと実行計画を常にキャプチャするようにするにはどうすればよいですか?

    これは、クエリの実行方法、クエリのキャプチャ方法、およびクエリの実行速度にすべて依存しているため、実際にはできません。多くの場合、クエリは完全にキャプチャされるのに十分な時間実行されないため、パラメータ情報を収集しないSQLServerの集約されたクエリ/プロシージャ統計ビューに依存する必要があります。トップSQLソースの収集設定を変更して、より多くの頻度でより多くのデータをキャプチャすることができますが、収集するデータの量と、それが購入する追加情報の量とのバランスをとる必要があります。

    レポートを自動化して生成できるように、情報を照会できますか?

    これを行うための箱から出してすぐに使えるものはありませんが、チームに戻して、どのようなオプションを考え出すことができるかを見てみましょう。このウェビナーで私が試したことの1つは、探している種類の回帰をキャッチするためのアドバイザリ条件を作成することでしたが、時間が要因になりました。

    OPTION(RECOMPILE)をいつ使用するかをどのように決定しますか 、毎日、さまざまなパラメータに対してさまざまな計画を立てていますか?

    パラメータの感度で最も変動するクエリから始めます。 2秒かかることもあれば、30秒かかることもあるクエリと、4秒から6秒の範囲のクエリがある場合は、
    最初のクエリに焦点を当てます。

    どちらを使用するのが良いか、 OPTION(RECOMPILE) またはQUERYTRACEON 、パラメータスニッフィングの場合。

    OPTION(RECOMPILE)が好きです 2つの理由で。 1つは、自己文書化です。コードを読んでいる人は誰もそれが何をしているのか不思議に思うことはありませんが、コードを読んでいる人全員が4136のようなTF番号を覚えているわけではありません。 ペオンとして。

    通常より時間がかかる手順について警告または報告することは可能ですか?カウント数の多い手順に最も関心があります。

    もちろん、アドバイザリ条件を使用することもできますが、収集しきい値を下回ることもあるプロシージャの場合、プロシージャ統計DMVのスナップショットを比較する必要があるため、少し複雑になる可能性があります。これについてもブログにリマインダーを追加しました。これは、過去にお客様が実装するのを支援したものだからです。

    Microsoftは、自動計画修正を含め、自動調整をAzureSQLDatabaseのデフォルトにしています。それはあなたにとって良い考えのように思われますか?

    私(または一部の顧客)がそれをいじくり回すまで、私は判断を保留します。調整方法を決定することは、人間にとって十分に挑戦的です。あなたのためにソフトウェアを書く人間は、それ以上ではないにしても、少なくとも同じくらい難しいようです。 Andyがこの質問を見たとき、SQL Server 2000を思い出させたと私に言いました。当時のマーケティングの売り込みは、DBAが不要になるほど自己調整されたということでした。その主張は十分に古くなっていません。

    クエリ履歴チャートで2つのドットを選択して比較できると、便利です。

    同意します。
    しばらくお待ちください。


    1. 一言で言えば軽い

    2. MySQLはCSVデータからNULL値をロードします

    3. SQL Server(T-SQL)でパーティションテーブルをクエリするときに、各行のパーティション番号を返す

    4. Oracleでサポートされている地域のリストを返す方法