数週間前にタイムアウトし始めたSQL Server 2012のトラブルシューティングを行っています。
サーバーは、毎分約15の警告の割合で、何千ものソート警告でいっぱいです。
並べ替えの警告を取得するには、次のクエリを使用しました。
DECLARE @log NVARCHAR(1000)
SELECT
@log = Substring(PATH, 1, Len(PATH) - Charindex('\', Reverse(PATH))) + '\log.trc'
FROM
sys.traces
WHERE
id = 1
SELECT
g.TransactionID, c.name as category, e.name as event,
g.hostname as servername, g.databasename as using,
g.sessionloginname as login, g.starttime, g.textdata as query
FROM
::fn_trace_gettable(@log, 0) as g
inner join
sys.trace_events e on g.eventclass = e.trace_event_id
inner join
sys.trace_categories as c on e.category_id = c.category_id
where
c.type not in ('0')
order by
starttime desc
ただし、textdata列は常に空です。
ソートの警告が古いストアドプロシージャから発生していることはほぼ間違いありません。しかし、毎分100を超えるストアドプロシージャがトリガーされているため、正確な原因を特定できません。警告の背後にあるクエリを見つけるにはどうすればよいですか?
更新:
SELECT
p.name, p.object_id, p.create_date, p.modify_date,
s.last_elapsed_time, s.last_worker_time,
(s.last_elapsed_time - s.last_worker_time) as time_difference,
s.execution_count, last_execution_time
FROM
SYS.dm_exec_procedure_stats as s
INNER JOIN
sys.procedures as p on p.object_id = s.object_id
WHERE
database_id = 11 AND s.last_worker_time < s.last_elapsed_time
ORDER BY
time_difference desc
いくつかの手順(3)では、last_elapsed_timeが200'000 +で、ワーカー時間がはるかに短いことを示しています。 1つは、15'000 +回実行されたことが際立っており、worker_timeより400'000 +より長い経過時間を持っています。そして、このクエリは確かにかなり大きなテーブルでソートを行います。
私が見ているものがソート警告の考えられる原因であるか、または私が輪になっているかどうか誰かに教えてもらえますか?.
クエリを少し調整して、「SpillToTempDb」の数、つまりソートの警告を取得できます。これにより、表示しているクエリのいずれかが問題である可能性があるかどうかがわかります。
WITH
XMLNAMESPACES (DEFAULT N'http://schemas.Microsoft.com/sqlserver/2004/07/showplan')
SELECT
p.name,
p.object_id,
p.create_date,
p.modify_date,
s.last_elapsed_time,
s.last_worker_time,
(s.last_elapsed_time - s.last_worker_time) as time_difference,
s.execution_count,
last_execution_time,
Query_Plan.value('count(/ShowPlanXML/BatchSequence/Batch/Statements/*/QueryPlan/Warnings/SpillToTempDb)', 'int') TempDbSpillWarnings
FROM SYS.dm_exec_procedure_stats as s
CROSS APPLY sys.dm_exec_query_plan(s.plan_handle) AS deqp
INNER JOIN sys.procedures as p on p.object_id = s.object_id
where database_id = 11 and s.last_worker_time < s.last_elapsed_time
order by time_difference DESC
それ以外の場合は、SQL Server 2012を使用しているため、拡張イベントを1時間ほど実行することをお勧めします。途中でそうするための良いガイドがあります このチュートリアル 。