設定を少し変更します。
まず、関心のあるすべてのプロダクトキーを一覧表示するテーブルを用意します...
CREATE TABLE product (
product_key INT NOT NULL,
price INT,
some_fact_data VARCHAR(MAX),
what_ever_else SOMEDATATYPE,
PRIMARY KEY CLUSTERED (product_key)
)
次に、レポートする必要のある個々の日付を含むカレンダーテーブルを作成します...
CREATE TABLE calendar (
date SMALLDATETIME,
is_bank_holdiday INT,
what_ever_else SOMEDATATYPE,
PRIMARY KEY CLUSTERED (date)
)
最後に、データテーブルに関連するすべてのフィールドのカバーインデックスがあることを確認します...
CREATE INDEX IX_product_day ON #ORDER_TURNOVER (product_key, day_key)
これにより、次のクエリが可能になります...
SELECT
product.product_key,
product.price,
calendar.date,
SUM(price) AS RSum
FROM
product
CROSS JOIN
calendar
INNER JOIN
#ORDER_TURNOVER AS data
ON data.product_key = product.product_key
AND data.day_key > dateadd(mm, -12, calendar.date)
AND data.day_key <= calendare.date
GROUP BY
product.product_key,
product.price,
calendar.date
このようにすべてを実行することにより、各product / calendar_dateの組み合わせは、すべて互いに連続しているデータテーブル内のレコードのセットに関連付けられます。これにより、集計するデータを検索する操作が、オプティマイザーにとってはるかに簡単になります。
[特に順序(製品、日付)で単一のインデックスが必要です。]
逆にインデックスがある場合、実際にははるかに困難です...
データ例:
product | date date | product
---------+------------- ------------+---------
A | 01/01/2012 01/01/2012 | A
A | 02/01/2012 01/01/2012 | B
A | 03/01/2012 02/01/2012 | A
B | 01/01/2012 02/01/2012 | B
B | 02/01/2012 03/01/2012 | A
B | 03/01/2012 03/01/2012 | B
左側のoyuは、365日ブロックで隣り合っているすべてのレコードを取得します。
右側では、集計する前に各レコードを検索します。検索は比較的簡単ですが、365回実行します。左のバージョンよりはるかに多い。