web-dev-qa-db-ja.com

ほとんどのクエリプランは過去4時間に再作成されました

SQL Serverデータベースのパフォーマンスに問題があります。このツール sp_BlitzCache を見つけました。コマンドの実行後、次のステートメントが得られました。

過去24時間に92.00%のプランが作成され、過去4時間に92.00%のプランが作成されています。

問題を特定しましたが(SQL Server Profilerを使用して、StmtRecompileイベントの発生を確認しました)、頻繁に再構築される少数の全文検索クエリのみを見つけることができました。ただし、全文検索クエリは、全クエリの約5%にすぎません。

残りの87%のプランの再現を引き起こす可能性のある提案はありますか?

SQL Server 2012(バージョン11.0.6567.0)を持っています。

編集:パフォーマンスカウンターを追加しました

+---------------------------+--------------------------------+--------------+
|        object_name        |          counter_name          |  cntr_value  |
+---------------------------+--------------------------------+--------------+
| SQLServer:Buffer Manager  | Background writer pages/sec    |            0 |
| SQLServer:Buffer Manager  | Buffer cache hit ratio         |        28436 |
| SQLServer:Buffer Manager  | Buffer cache hit ratio base    |        28436 |
| SQLServer:Buffer Manager  | Checkpoint pages/sec           |      8259452 |
| SQLServer:Buffer Manager  | Database pages                 |      4434337 |
| SQLServer:Buffer Manager  | Free list stalls/sec           |            9 |
| SQLServer:Buffer Manager  | Integral Controller Slope      |            0 |
| SQLServer:Buffer Manager  | Lazy writes/sec                |         5608 |
| SQLServer:Buffer Manager  | Page life expectancy           |       438901 |
| SQLServer:Buffer Manager  | Page lookups/sec               | 122694703703 |
| SQLServer:Buffer Manager  | Page reads/sec                 |     60994608 |
| SQLServer:Buffer Manager  | Page writes/sec                |    126076564 |
| SQLServer:Buffer Manager  | Readahead pages/sec            |     45305420 |
| SQLServer:Buffer Manager  | Target pages                   |    130990080 |
| SQLServer:Buffer Node     | Database pages                 |      4434337 |
| SQLServer:Buffer Node     | Page life expectancy           |       438901 |
| SQLServer:Buffer Node     | Local node page lookups/sec    |            0 |
| SQLServer:Buffer Node     | Remote node page lookups/sec   |            0 |
| SQLServer:Memory Manager  | External benefit of memory     |            0 |
| SQLServer:Memory Manager  | Connection Memory (KB)         |         3304 |
| SQLServer:Memory Manager  | Database Cache Memory (KB)     |     35474784 |
| SQLServer:Memory Manager  | Free Memory (KB)               |     13229808 |
| SQLServer:Memory Manager  | Granted Workspace Memory (KB)  |            0 |
| SQLServer:Memory Manager  | Lock Memory (KB)               |       455928 |
| SQLServer:Memory Manager  | Lock Blocks Allocated          |      1798154 |
| SQLServer:Memory Manager  | Lock Owner Blocks Allocated    |      3568588 |
| SQLServer:Memory Manager  | Lock Blocks                    |        10562 |
| SQLServer:Memory Manager  | Lock Owner Blocks              |        10617 |
| SQLServer:Memory Manager  | Maximum Workspace Memory (KB)  |     43368000 |
| SQLServer:Memory Manager  | Memory Grants Outstanding      |            0 |
| SQLServer:Memory Manager  | Memory Grants Pending          |            0 |
| SQLServer:Memory Manager  | Optimizer Memory (KB)          |         1400 |
| SQLServer:Memory Manager  | Reserved Server Memory (KB)    |            0 |
| SQLServer:Memory Manager  | SQL Cache Memory (KB)          |       229112 |
| SQLServer:Memory Manager  | Stolen Server Memory (KB)      |      8063232 |
| SQLServer:Memory Manager  | Log Pool Memory (KB)           |         4192 |
| SQLServer:Memory Manager  | Target Server Memory (KB)      |     56934400 |
| SQLServer:Memory Manager  | Total Server Memory (KB)       |     56767824 |
| SQLServer:Memory Node     | Database Node Memory (KB)      |     35474784 |
| SQLServer:Memory Node     | Free Node Memory (KB)          |     13229808 |
| SQLServer:Memory Node     | Foreign Node Memory (KB)       |            0 |
| SQLServer:Memory Node     | Stolen Node Memory (KB)        |      8063208 |
| SQLServer:Memory Node     | Target Node Memory (KB)        |     56934376 |
| SQLServer:Memory Node     | Total Node Memory (KB)         |     56767800 |
+---------------------------+--------------------------------+--------------+
9

プラン作成時間をテストするために使用されるクエリはこれです

WITH x AS (
SELECT SUM(CASE WHEN DATEDIFF(HOUR, deqs.creation_time, SYSDATETIME()) <= 24 THEN 1 ELSE 0 END) AS [plans_24],
       SUM(CASE WHEN DATEDIFF(HOUR, deqs.creation_time, SYSDATETIME()) <= 4 THEN 1 ELSE 0 END) AS [plans_4],
       SUM(CASE WHEN DATEDIFF(HOUR, deqs.creation_time, SYSDATETIME()) <= 1 THEN 1 ELSE 0 END) AS [plans_1],
       COUNT(deqs.creation_time) AS [total_plans]
FROM sys.dm_exec_query_stats AS deqs
)
SELECT CONVERT(DECIMAL(3,2), NULLIF(x.plans_24, 0) / (1. * NULLIF(x.total_plans, 0))) * 100 AS [percent_24],
       CONVERT(DECIMAL(3,2), NULLIF(x.plans_4 , 0) / (1. * NULLIF(x.total_plans, 0))) * 100 AS [percent_4],
       CONVERT(DECIMAL(3,2), NULLIF(x.plans_1 , 0) / (1. * NULLIF(x.total_plans, 0))) * 100 AS [percent_1],
       @@SPID AS SPID
INTO #plan_creation
FROM x
OPTION (RECOMPILE) ;

SPは、さらに調査を開始する場所についての手がかりも提供します

これらのパーセンテージが高い場合は、メモリ不足またはプランキャッシュの不安定性の兆候である可能性があります

上記の手がかり以外に、サーバーが再起動されているかどうかを確認してください。

サーバーが再起動されない場合、以下は私がとるアプローチです

  • あなたが直面しているメモリプレッシャーかどうかを確認してください

最初に、メモリ設定が最適に構成されているかどうかを確認します。そうである場合、以下のカウンタを使用して、メモリの負荷に直面しているかどうかを確認できます

メモリ:利用可能なMB
SQLバッファ:無料ページ
SQLバッファー:ページの寿命
SQLバッファー:遅延書き込み

メモリ不足に直面している場合は、より多くのメモリを使用しているクエリを確認および調整するか、メモリを追加してみてください。

再コンパイルを引き起こすクエリを実行した可能性があります

  • クエリによって参照されるテーブルまたはビューに加えられた変更(ALTER TABLEおよびALTER VIEW)。

  • キャッシュからそのプロシージャのすべてのプランを削除する単一のプロシージャに加えられた変更(ALTER PROCEDURE)。

  • 実行プランで使用されるインデックスへの変更

  • UPDATE STATISTICSなどのステートメントから明示的に生成されるか、自動的に生成される、実行プランで使用される統計の更新。

  • 実行プランで使用されているインデックスを削除する。

プランのキャッシュの詳細については、このホワイトペーパーもご覧ください。

https://technet.Microsoft.com/en-us/library/ee343986(v = sql.100).aspx

6
TheGameiswar

@TheGameiswarの発言を追加するには、このクエリを実行して、キャッシュから取得されていないプランの詳細を確認することもできます。

;with
    xmlnamespaces (N'http://schemas.Microsoft.com/sqlserver/2004/07/showplan' as DYN)
select
    db_name(st.dbid) as DBName
    , object_schema_name(st.objectid, st.dbid) as SchemaName
    , object_name(st.objectid, st.dbid) as ObjectName
    , ecp.objtype
    , st.text
    , qp.query_plan.value('(/DYN:ShowPlanXML/DYN:BatchSequence/DYN:Batch/DYN:Statements/DYN:StmtSimple/@RetrievedFromCache)[1]', 'varchar(100)') as RetrievedFromCache
    , qp.query_plan
into #temp
from sys.dm_exec_cached_plans ecp
    outer apply sys.dm_exec_query_plan(ecp.plan_handle) qp
    outer apply sys.dm_exec_sql_text(ecp.plan_handle) st

select
    *
from #temp t
where t.RetrievedFromCache is null
    and t.DBName is not null
order by t.DBName, t.SchemaName, t.ObjectName;
2
Dean Savović