現在シングルユーザーの負荷がかかっているアプリのテスト-テストデータが本番サイズ(テーブルあたり400k〜2M行)に増加したため、一部のSELECT spは十分に高速ではなくなりました(テストデータが限られているため、以前はそれぞれ30ミリ秒未満でしたが、現在は100〜200ミリ秒ですが、数ミリ秒あるため、UIで遅延が明らかになっています)。
現在シングルユーザーの負荷がかかっているアプリのテスト-テストデータが本番サイズ(テーブルあたり400k〜2M行)に増加したため、一部のSELECT spは十分に高速ではなくなりました(テストデータが限られているため、以前はそれぞれ30ミリ秒未満でしたが、現在は100〜200ミリ秒ですが、数ミリ秒あるため、UIで遅延が明らかになっています)。
回答:
使用できますDBCC SQLPERF("waitstats")
。これは、SQLサーバーが待機していたタスクの待機時間を返します。各カウンターの詳細な説明はオンラインで見つけることができます。この情報を使用して、ボトルネックを見つけることができます。
また、クエリアナライザーでクライアント統計をオンにして、クライアント側の待機時間を確認します。
最初のテスト以降、ハードウェアは変更されていないと想定しています。したがって、ハードウェアは一定であるため、疑いはありません。
考え:
いくつかの解決策:
不足しているインデックスDMVを実行して、不足しているインデックスを確認します。
SELECT
migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure,
'CREATE INDEX [missing_index_' + CONVERT (varchar, mig.index_group_handle) + '_' + CONVERT (varchar, mid.index_handle)
+ '_' + LEFT (PARSENAME(mid.statement, 1), 32) + ']'
+ ' ON ' + mid.statement
+ ' (' + ISNULL (mid.equality_columns,'')
+ CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN ',' ELSE '' END
+ ISNULL (mid.inequality_columns, '')
+ ')'
+ ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement,
migs.*, mid.database_id, mid.[object_id]
FROM sys.dm_db_missing_index_groups mig
INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle
WHERE migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) > 10
ORDER BY migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC
...そして最も高価なDMVクエリ
SELECT TOP 20
qs.sql_handle,
qs.execution_count,
qs.total_worker_time AS Total_CPU,
total_CPU_inSeconds = --Converted from microseconds
qs.total_worker_time/1000000,
average_CPU_inSeconds = --Converted from microseconds
(qs.total_worker_time/1000000) / qs.execution_count,
qs.total_elapsed_time,
total_elapsed_time_inSeconds = --Converted from microseconds
qs.total_elapsed_time/1000000,
st.text,
qp.query_plan
FROM
sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
CROSS apply sys.dm_exec_query_plan (qs.plan_handle) AS qp
ORDER BY qs.total_worker_time DESC
それ以外の場合、このSOの質問は、私や他のSQL高担当者タイプから良いヒントがあります:https://stackoverflow.com/q/4118156/27535(私はすべての3つの長めの答えをコピー/ペーストしません)
考慮すべき興味深いことは、実行中のMSSQL 2000のバージョンです。
バイナリには4つのバージョンがあります
これらの各バージョンには、RAMとCPUに関して制限があります。
現在保存されているデータの量が、MSSQL 2000のバージョンの機能を超えて、クエリ/サブクエリを実行するために追加のRAMが必要になるか、CPU使用率が不十分である可能性を探る価値があります。バイナリバージョンをMSSQL 2000 Entrpriseバージョン(おそらく、MSSQLのバージョンが古くなっているので長い目で見たもの)、または予算に余裕のある最高のバージョンにアップグレードする必要があるかもしれません。
2008年が最新であり、現在サポートが利用可能であるため、MSSQL 2000から抜け出すこともできます。繰り返しますが、これは予算の問題になる可能性があります。すでにエンタープライズを使用している場合、または予算でメジャーアップグレードを許可できない場合は、DB統計またはDB設計を検討できます。
免責事項:私はSQL ServerのDBAではありません