月(および年)でグループ化する必要があり、次のことを考えていました。
GROUP BY CAST(YEAR(tDate) AS NVARCHAR(4)) + '-' + CAST(MONTH(tDate) AS NVARCHAR(2))
しかし、私はウェブで次のようなものを見つけました:
GROUP BY YEAR(tDate), Month(tDate)
どちらも同等ですか? 2番目を使用する方が良いですか?
2番目のアプローチを使用する必要があります。文字列の連結と型変換はすべて、クエリに不要なCPUオーバーヘッドを追加するだけです。
Stack Overflowスキーマでこれを試すことができます。ユーザーのテーブルをクエリして、日付フィールドにサポートする非クラスター化インデックスを作成します。
CREATE NONCLUSTERED INDEX IX_CreationDate ON dbo.Users (CreationDate);
最初のアプローチの例を次に示します。
SELECT
CAST(YEAR(u.CreationDate) AS NVARCHAR(4))
+ '-'
+ CAST(MONTH(u.CreationDate) AS NVARCHAR(2)),
COUNT(*)
FROM dbo.Users u
GROUP BY
CAST(YEAR(u.CreationDate) AS NVARCHAR(4))
+ '-'
+ CAST(MONTH(u.CreationDate) AS NVARCHAR(2));
そして 計画 と統計:
Table 'Worktable'. Scan count 0, logical reads 0
Table 'Workfile'. Scan count 0, logical reads 0
Table 'Users'. Scan count 1, logical reads 675
SQL Server Execution Times:
CPU time = 203 ms, elapsed time = 258 ms.
それを2番目のアプローチと比較します。
SELECT
YEAR(u.CreationDate), Month(u.CreationDate),
COUNT(*)
FROM dbo.Users u
GROUP BY YEAR(u.CreationDate), Month(u.CreationDate);
計画 とその統計は次のとおりです。
Table 'Worktable'. Scan count 0, logical reads 0
Table 'Workfile'. Scan count 0, logical reads 0
Table 'Users'. Scan count 1, logical reads 675
SQL Server Execution Times:
CPU time = 125 ms, elapsed time = 229 ms.
ご覧のとおり、文字列の連結/キャストのアプローチでは、わずかに多くのCPUが使用されます。他はすべて同じです。
ちなみに、dbo.Usersテーブルには約300,000行しかありません。約3,700,000行が含まれているdbo.Postsテーブルでこれと同じ演習を行うと、クエリが並列になり、2番目のアプローチのCPU節約がはるかに大きくなります。
したがって、一般的なケースでは、CPUに関して2番目のアプローチの方が優れているだけでなく、データサイズが大きくなるほど、スケーリングが向上するように見えます。