2016-08-16 20 views
0

実行するのに時間がかかりますが、同じテーブルでcount(*)を同じWHERE句が1秒以内に戻ります。非常に遅く実行されている単純な選択クエリですが、同じテーブルの選択は非常に高速です

このクエリは非常に長い時間(1時間+)のために実行します:

SELECT col1 
     , col2 
     , col3 
    FROM Table 
    WHERE RowInsertDate >= @SomeStartDate 
    AND RowInsertDate < @SomeEndDate 

しかし、このクエリは1秒未満で戻ってくる:

SELECT count(*) 
    FROM Table 
    WHERE RowInsertDate >= @SomeStartDate 
    AND RowInsertDate < @SomeEndDate  

テーブル34万行を持って、主キーに使用されるID列と地理的領域(北、南、東、西)の列があります。列 'RowInsertDate'は、行がテーブルに挿入された日付です。上記のクエリの期待される結果は、それぞれ 'no rows'と '0'です。

このテーブルのクラスタ化インデックスは、(ID、geoRegion)ASCです。このテーブルには、RowInsertDate ASCにクラスター化されていないインデックスもあります。

ここからどこに行くのかわかりません。誰もこれに前に遭遇しましたか?

+0

ボリュームのものである可能性があります。返される行の数 – Paparazzi

+0

これは、実行計画があなたと私たちを支援するものです。また、誰かが選択したcol1、col2をあなたが気づいているインデックスに関連付ける方法はありません。私たちはそれが正しいかどうか分かりません。 – Matt

+0

両方のクエリが異なり、異なる実行計画につながります。両方の実行計画を提供できます – TheGameiswar

答えて

1

select count(*)を実行すると、SQL Serverはインデックスから行を数えることができます。 select col1,col2,col3を実行すると、インデックスにあるすべての行について、SQL Serverはクラスタードインデックスキー値(ID、geoRegion、インデックスに格納されている)を取得し、そのクラスタードインデックスキー値を持つテーブルから見つかったすべての行を検索する必要があります。

また、クラスタードインデックスのすべてのルックアップを行うことがより効果的と考えられる場合、SQL Serverはクラスタードインデックススキャン(または他のもの)を行うこともできます。クエリプランで何が起きているかを確認できます。

クエリを高速化するには、選択する必要がある列をRowInsertDateにインクルード列または通常列として追加することを検討します。これはもちろん、列の数が比較的少ない場合(またはテーブルが更新されない場合)にのみ意味があります。

0

実行計画を確認することはできますが、これは一般的なブックマーク検索の問題です。これは、リソースを消費し、時間を消費します。 1つの解決策は、それに対処するためのCOVERING INDEXを作成することです。

これらの2つのクエリの実行時間は、まったく異なるものを実行しているために異なります。

もちろん、列(col1、col2、col3)がどのデータ型であるかを確認する必要があります。

これ以外にも、SET NOCOUNT ONを設定することができます。それが役に立てば幸い。

-2

クエリは非常に簡単なので、

SELECT col1 
    , col2 
    , col3 
FROM Table (nolock) 
WHERE RowInsertDate >= @SomeStartDate 
AND RowInsertDate < @SomeEndDate 
+2

これは危険な勧告です – Paparazzi

+0

@パパラッチ:選択クエリのnolockは危険ですか? –

+0

@AnjaniKumarAgrawal http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/ – scsimon

0

IDが一意である場合(例えば同一性)、私はあなたがPKだけではクラスタ化されたことを確認勧め:私は何が不足していることはNOLOCKだと思います。余分な列では、ルックアップのために余分なデータを運ばなければならない。

私はgeoRegionが1バイトであることを希望します。 varcharの場合、必要なボリュームを10倍にしています。これは、同じ量のメモリ内のインデックスの1/10です。

上記の場合は、追加し、それを修正しないインデックスの対応が遅れて申し訳ありません

CREATE NONCLUSTERED INDEX IX_Table_RowInsertDate 
ON Table (RowInsertDate) 
INCLUDE (col1, col2, col3); 
0

でそれらの列が含まれます。

サーバー自体に何らかの問題があるようです。私たちのログにはIOに関する問題がたくさんあります。 DBAにサーバーを再起動させ、クエリがすぐに実行されました。

正確な問題の性質はどういうものか分かりませんが、今解決しました。同じことがもう一度起こったら別の質問を投稿します。

関連する問題