5

SQL Server 2008 R2 を使用したデータ ウェアハウスのスケールアップでは、著者は、クエリ速度を最適化するために、ファクト テーブルのクラスター化インデックスとして YYYYMMDD の形式の整数日付キーを使用することを推奨しています。

キー日付フィールドを日付キーに変換する最良の方法は何ですか? 以下はうまくいくと思いますが、少しずさんです:

select Replace(CONVERT(varchar,GETDATE(),102),'.','')

明らかに、私は getdate を使用していませんが、集計で使用するテーブルの日付列を使用しています。

まず、この変換をどのように行うことをお勧めしますか? 私の考えは受け入れられますか?

次に、Date Key をクラスター化インデックスとして使用して成功した人はいますか?

4

3 に答える 3

10

ISO long(112)でうまくいきます:

SELECT CONVERT(INT, CONVERT(VARCHAR(8), GETDATE(), 112))

getdate()をISO 112でintに直接キャストすると、何らかの理由で41008が得られますが、VARCHARを介して実行することは機能しているようです。より高速なキャストを考えている場合は更新します。

編集:int only vs varcharの議論に関して、ここに私の発見があります(私のテストリグとプロダクションサーバーで繰り返すことができます)Varcharメソッドは50万回のキャストでより少ないCPU時間を使用しますが、全体的にわずかに遅くなります-何十億もの行

編集2:キャッシュと異なる日付をクリアするようにテストケースを改訂

DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
SET STATISTICS TIME ON;
WITH    RawDates ( [Date] )
          AS ( SELECT TOP 500000
                        DATEADD(DAY, N, GETDATE())
               FROM     TALLY
             )
    SELECT  YEAR([Date]) * 10000 + MONTH([Date]) * 100 + DAY([Date])
    FROM    RawDates
SET STATISTICS TIME OFF 

(500000 row(s) affected)

 SQL Server Execution Times:
   CPU time = 218 ms,  elapsed time = 255ms.    
DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
SET STATISTICS TIME ON;
WITH    RawDates ( [Date] )
          AS ( SELECT TOP 500000
                        DATEADD(DAY, N, GETDATE())
               FROM     TALLY
             )
    SELECT  CONVERT(INT, CONVERT(VARCHAR(8), [Date], 112))
    FROM    RawDates
SET STATISTICS TIME OFF 

(500000 row(s) affected)

 SQL Server Execution Times:
   CPU time = 266 ms,  elapsed time = 602ms
于 2012-04-10T15:33:49.497 に答える
4

文字列への変換とその逆は、驚くほど遅くなる可能性があります。代わりに、次のように整数を完全に処理できます。

Select Year(GetDate()) * 10000 + Month(GetDate()) * 100 + Day(GetDate()) 

私の簡単なテストでは、これは文字列に変換してから int に変換するよりもわずかに高速です。Year、Month、および Day 関数はそれぞれ整数を返すため、パフォーマンスがわずかに向上します。

于 2012-04-10T15:56:35.267 に答える
4

YYYYMMDD 形式を使用して DateKey を作成する代わりに、DATEDIFF関数を使用して、0 (つまり、「0 で表される日付」) と DateKey を作成する日付の間の日数を取得できます。

SELECT DATEDIFF(day,0,GETDATE())

欠点は、値を見て日付を特定するのは簡単ではありませんが、DATEADD関数を使用して元の日付を計算できることです (このトリックを使用して日時の時刻部分を切り捨てることも見てきました)。

SELECT DATEADD(day, 41007, 0)

(注: 41007 は、上記の DATEDIFF 関数を 2012 年 4 月 10 日に実行したときの結果です。)

于 2012-04-10T16:15:04.063 に答える