常時スキャンには0秒または2〜3分かかります


9

行を返さないことが保証されている以下のようなクエリは、いずれかのサーバーで0〜160秒かかります。

select col1, col2, col3
from tab1
where 0 = 1

2週間前、これは48時間の間隔で6回発生しました。先週、同じクエリにかかった時間は〜0秒でした。アプリケーションのSQLのログはありますが、容疑者はまだ見つかりません。さらに、上位0 / where 0 = 1タイプのクエリはデータページにヒットしないので、行/ページ/テーブルレベルのデータロックに耐性があると思いましたか?スキーマは(既知の)SQLの影響を受けません。

問題が一貫しておらず、サーバーに非常に大きな負荷がかかっているため、SQLプロファイラーを接続する前に何が起こっているのかについての理論を理解したいと思います。他のクエリは、これらの遅延中に問題なく実行されます。アプリケーションの既知の問題は、動的に作成された多数のSQLクエリです-48時間にわたって合計850k(ログ)クエリのうち約200kの一意のクエリは、このような問題を引き起こす可能性がありますか?

サーバーはSQL Server 2005 Standard Edition、96 GB RAM、SAN上のディスクおよび4 CPU / 16コアを実行しています。データベースファイルとファイルグループは十分に最適化されており、問題にはなりません(ただし、これについては個別に調査しています)。

どこを見ればよいかについてのポインタは大歓迎です。

編集:完璧です!クエリを再生して実行プランを追加したところ、1分35秒かかりました。クエリ期間を示す実行プランとスクリーンショットは次のとおりです。 クエリプラン

編集2:2回目の実行の統計時間の詳細。現在、一貫して遅いようですので、プロファイラーとperfmonを接続します:

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 97402 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

実行計画を含めていただけませんか?実行前にクエリウィンドウでCtrl + Mキーを押します。
Craig Efrein 2014年

2
ロックの問題でしょうか?テーブルでの選択をブロックする他のセッションからのDMLステートメント(SQL Server 2005でのデフォルトの動作)
a_horse_with_no_name

考えられる唯一の原因である、既知のDMLステートメントはありませんが、まだ調査中です。実行計画が質問に追加されます。
EventHorizo​​n 2014年

私が読んだことから、これは返される行がないことをオプティマイザが知っているときにヒープとインデックスの読み取りを回避するためにMSSQLが使用するこれらの簡単な実行計画の1つにすぎません
Craig Efrein

1
このように見えるケースを見た。統計の更新をトリガーしていることがわかりました(統計の自動更新がオンになっていて、保守計画が壊れていました)。
ジョシュア

回答:


18

たとえ... WHERE 0 = 1節があってもIS、テーブルにインテント共有()ロックが引き続き必要であるように見えます。これを証明しましょう:

まず、テストテーブルを作成します。

use TestDb1;
go

create table dbo.MyTestTable1
(
    Id int identity(1, 1) not null,
    SomeInt int not null
);
go

insert into dbo.MyTestTable1 (SomeInt)
values (10), (20), (30), (40), (50);
go

これでテストテーブルが作成されたので、1つのセッション(クエリウィンドウ)で次のコードを実行して、排他(X)ロックをオンにしdbo.MyTestTable1ます。

use TestDb1;
go

begin tran;
    select
        Id, SomeInt
    from dbo.MyTestTable1 with (tablockx);
--commit tran;

sys.dm_tran_locksDMVを見て、排他ロックを確認できます。次に、別のセッション(新しいクエリウィンドウ)で、クエリの内容を正確に実行します。

use TestDb1;
go

select
    Id, SomeInt
from dbo.MyTestTable1
where 0 = 1;

一見、完了していないようです。を見るとsys.dm_exec_requests、これが事実である理由が正確にわかります。

select
    r.session_id,
    r.status,
    r.wait_type,
    r.wait_time,
    r.wait_resource,
    r.blocking_session_id
from sys.dm_exec_requests r
cross apply sys.dm_exec_sql_text(r.sql_handle) st
where st.text like '%where 0 = 1%'
and r.session_id <> @@spid;

ここに画像の説明を入力してください

... WHERE 0 = 1クエリがISこのオブジェクトのロックを待機していることがわかります(object_idはに変換されますdbo.MyTestTable1)。

私は決して同時実行性があなたの問題であると言っているのではなく、その音によってあなたは症状を示しています。上記の例は、WHEREデータを返さない句がある場合でも、ロックとブロックが免除されていないことを証明するためのものです。

私たちにできることは推測だけなので、「時間がかかる」場合に必要なのは、その要求が実行している処理を正確に確認することです。それが何かを待っているなら、それが待っているものを見てください。


1

クエリを要求するスパイクとスレッドの程度によっては、システムが単にそのクエリをキューに入れている可能性があります。セットアップのデフォルトのワーカー数(つまり、同時SQLサーバースレッドの数)は約700になるはずです。

sys.dm_os_schedulersおよびsys.dm_os_waiting_tasksをチェックして、それが問題であるかどうかを確認してください。


良い提案ですが、結局のところ問題はばかげたロックになりました。
EventHorizo​​n 2014年

700人の労働者はたくさんいるので、私は本当に確信していませんでしたが、簡単にチェック(したがって除外)できました
Sascha Rambeaud 14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.