web-dev-qa-db-ja.com

警告を並べ替え、背後にあるクエリを見つける

数週間前にタイムアウトし始めた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 +より長い経過時間を持っています。そして、このクエリは確かにかなり大きなテーブルでソートを行います。

私が見ているものがソート警告の考えられる原因であるか、または私が輪になっているかどうか誰かに教えてもらえますか?.

2
Reaces

クエリを少し調整して、「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時間ほど実行することをお勧めします。途中でそうするための良いガイドがあります このチュートリアル

2
Mark Sinkinson