2017-01-12 11 views
0

いくつかのシナリオを作成するのではなく、クエリを再利用しようとしています。基本的に私は大きなテーブルからカウントを取得しています。WHERE句に基づくSQLのパフォーマンス

の質問がされています。私は基本的に2つのクエリが同じものを返す代わりに

シンプル
SELECT COUNT(id) FROM [Documents] 

SELECT COUNT(id) FROM [Documents] WHERE UploadDate > '1900/1/1' AND UploadDate < GETDATE() 

を使用していた場合、私は、長期的にパフォーマンスを失うつもりですこの場合、すべてのレコードを返す必要があるからです。しかし、他の状況下では、日付ペアは異なるパラメータを使用します。

+0

その列にインデックスがある場合、それは問題ではありません。 –

+0

サンプルデータと望ましい結果を提供してください。 –

+0

おそらく。クラスタード・インデックス(および主キー)が存在するかぎり、単純な(2番目の)照会が優先され、できるだけ高速になります。 where句を追加することで、パフォーマンスを低下させることができますが、フィルタリング対象の列とその列に含まれるデータのインデックスに依存します。 – Igor

答えて

0

いくつかのパラメータに基づいてカウントを行う場合は、インデックスがUploadDateに定義されている場合、大きな違いはないと私は考えています。ストアドプロシージャを使用している場合、それは次のようになります。

CREATE PROCEDURE dbo.GetCount 
(
    @FromDate DATETIME2 = '1900-01-01', 
    @ToDate DATETIME2 = '9999-12-31', 
    -- other filters may come here 
) 
AS 
BEGIN 
    SELECT COUNT(id) 
    FROM [Documents] 
    WHERE UploadDate > @FromDate AND @ToDate < @ToDate 
END 
GO 

-- get all 
EXEC dbo.GetCount 
-- get from date 
EXEC dbo.GetCount @FromDate = '2015-03-01' 
-- to date 
EXEC dbo.GetCount @ToDate = '2016-03-01' 
-- both 
EXEC dbo.GetCount @FromDate = '2015-03-01', @ToDate = '2016-03-01' 

あなたはまた、は、動的SQL作成することによって、実行するための最低限のSQLを取得しようとすることができます:

CREATE PROCEDURE dbo.GetCount 
(
    @FromDate DATETIME2 = NULL, 
    @ToDate DATETIME2 = NULL 
    -- other filters may come here 
) 
AS 
BEGIN 
    DECLARE @SQL NVARCHAR(4000) = N' 
     SELECT COUNT(id) FROM [Documents] 
     WHERE 1 = 1 
    ' 
    IF (@FromDate IS NOT NULL) @SQL = @SQL + ' UploadDate > @FromDate' 
    IF (@ToDate IS NOT NULL) @SQL = @SQL + ' UploadDate > @ToDate' 

    EXECUTE sp_executesql @SQL, '@FromDate DATETIME2, @ToDate DATETIME2', @FromDate, @ToDate 
END 

これを左および/または右に開いた間隔の柔軟性を提供する。

のアプリケーション層(たとえばLINQ2SQL)からクエリを動的に生成する場合は、パラメータに基づいて最適なオプションを生成することができます。これにより、最短で最速のクエリが得られます。

var query = DbContext.Documents; 
if (fromDate.HasValue) query = query.Where(UploadDate > fromDate.Value); 
if (toDate.HasValue) query = query.Where(UploadDate < toDate.Value); 
int count = query.Count(); 

最後の2つのソリューションでも、新しいフィルタを簡単に追加できます。

0

あなたはすべてして、条件を満たすものカウントしたい場合:

SELECT COUNT(id) as total_cnt, 
     SUM(CASE WHEN UploadDate > '1900-01-01' AND UploadDate < GETDATE() 
       THEN 1 ELSE 0 
      END) as specific_cnt 
FROM [Documents] d; 
+1

それは本当に質問に答えていません –

0

を使用すると、範囲値に基づいてパフォーマンスを変える心配している場合は、クエリで指定し、理由パラメータのスニッフィングクエリの最後にOPTION (RECOMPILE)を追加することができます。

SELECT COUNT(id) 
FROM [Documents] 
WHERE UploadDate > '1900/1/1' AND UploadDate < GETDATE() 
OPTION (RECOMIPLE) 

これは、新しく生成されたプランは、あなたが'2011/1/1'から始めてチェックすることにした場合オプティマイザは、その日付範囲のために、自分自身で、その瞬間に、思い付く可能性が最善であることを確認します例。