2016-06-13 11 views
3

これは、クエリであるところでは、私は、クエリを6万件のレコードをテーブルの上に20秒を取っているSQL Serverの:数のパフォーマンス()句

SELECT COUNT(*) 
FROM tbl 
WHERE intCol = @intval 
    AND varcharCol = @varchr 
    AND (datetimeCol BETWEEN @from AND @to) 

を持っています。データが20倍以上になるので、私にとっては非常に悪いことです。それをより速くする方法はありますか?

私は(intColvarcharColdatetimeCol)上の所定の位置に複合インデックスを持っているし、実行計画を示しインデックス・スキャン(cost 91%) - >stream aggregate (cost 9%) - >計算スカラ(cost 0%)

は非常に数を交換して任意のヘルプ

+0

インデックス付きビューhttp://aboutsqlserver.com/2011/03/24/indexed-materialized-views-in-microsoft-sql-server/を考えてみましょう – Bas

+0

まず、インデックスを置くしようとすることができあなたの**プライマリキー**のようなもの** - IDのようなもの)。それは単なる4バイトの 'int'なので、インデックスは行の数を決定するために読み込まれるページ数が少なくて済みます。または、システムカタログビューを使用してテーブルの行の概数**を取得することもできます –

+0

SQL Serverのバージョンによっては、特に日付範囲の一部を考慮して、列ストアインデックスを考慮することもできますあなたの質問。 –

答えて

0

に感謝します(@TheIDOfyourTable)

+0

'TheIDOfyourTable'カラムだけにクラスタ化されていない別のインデックスがない限り、それは' SELECT COUNT(*) 'より速くはありません。 .... –

0

迅速なカウントのための簡単な使用のコード行

SELECT  count(1) 
FROM   tbl 
+0

これは 'SELECT COUNT(*)'より速くなることはありません...... –

3

テーブルにデータ型がどのようなものであるか尋ねることができますか?また、どのタイプのマシンを実行していますか?

何かが足りないようです。私はいくつかのテストデータを用意して上記のクエリを実行しました。maxdop 1で実行していても、ほぼ即座にクエリが実行されます。

ここに私のテストデータがあります:あなたは、データのサイズので、限り、彼らは許容値のドメイン内にあり、あなたがほとんど保証一致していると数字の任意の組み合わせを選択することができます以下

create table dbo.tbl (
    intCol int, 
    varcharCol varchar(128), 
    datetimeCol datetime); 

insert tbl (
    intCol, 
    varcharCol, 
    datetimeCol) 
select top (6000000) 
    abs(checksum(newid())) % 100, 
    abs(checksum(newid())) % 100, 
    convert(datetime, abs(checksum(newid())) % 50000) 
from sys.all_columns a 
cross join sys.all_columns b; 

create nonclustered index uc 
    on tbl (intCol, varcharCol, datetimeCol); 

セットはかなりです。

declare 
    @intval int = 50, 
    @varchr varchar(128) = '55', 
    @from datetime = '1900-01-01', 
    @to datetime = '1950-01-01'; 

set nocount on; 
set statistics io on; 
set statistics time on; 

select count(*) -- select * 
from tbl 
where intCol = @intval 
    and varcharCol = @varchr 
    and datetimeCol between @from and @to 
option (maxdop 1); 

set statistics time off; 
set statistics io off; 

結果は、実行時間が最小であることを示しています。

 
----------- 
221 

Table 'tbl'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 


SQL Server Execution Times: 
    CPU time = 0 ms, elapsed time = 0 ms. 

また、私が見るクエリプランは、元の投稿で述べたものと似ています。これは、集約とwhere句を使用した簡単なクエリの典型的な実行計画とコストです。

Query Cost

+0

カラムストアインデックスを使用するように変更する前に、開発マシンまたはローカルボックスからこれらのテストを実行していますか?メモリの制約に遭遇する可能性があり、マシンが仮想メモリ(ページングなど)を使用しているのかどうか疑問に思うだけです。SQL Serverが適切な環境でこのクエリのニーズを満たすことができないのは間違いです。これはまさにSQLが非常にうまくいくように設計されたものです。 – Yobik

+0

Yobikの返信をありがとう、私は8GBの物理RAMで4GBのコミットを持っている開発マシンでそれをやっています。クエリは、おそらくキャッシュのために2回目にほとんど瞬時に実行されます。私はそれがあなたのためにとても素早く働いているのかと思っています。クエリを実行する前に DBCC DROPCLEANBUFFERS を実行してみることはできますか。これはいくつかのキャッシュをクリアするはずです – Balok

+0

Balok - 私はこれを別の開発マシンで実行しました。これは他の開発ボックスと一貫しています。 「経過時間= 2ms」となる。また、クエリ実行前に 'dbcc dropcleanbuffers;'を実行して同様の結果を得ました。 btw - 最初の開発ボックスにはSSDがあり、2番目の開発ボックスにはスピンドルが使用されています。 – Yobik

関連する問題