I次の2つの表があります。SQL Serverの:WHERE句内に複数のCTEとサブクエリを持つクエリのパフォーマンスを向上させる方法
CREATE TABLE Portfolio.DailyStats
(
Date date NOT NULL Primary Key,
NAV int NOT NULL,
SP500 decimal(8,4) NULL,
R2K decimal(8,4) NULL,
NetExp decimal(8,4) NULL,
GrossExp decimal(8,4) NULL,
)
GO
ALTER TABLE Portfolio.DailyStats
ADD [YrMn] as CONVERT(varchar(7), Date)
GO
80間:ここ
CREATE TABLE Portfolio.DailyPortfolio
(
BbgID varchar(30) NOT NULL,
Ticker varchar(22) NULL,
Cusip char(9) NULL,
SecurityDescription varchar(50) NOT NULL,
AssetCategory varchar(25) NOT NULL,
LSPosition char(3) NULL,
Ccy varchar(25) NOT NULL,
Quantity int NULL,
AvgCost decimal(7,3) NULL,
PriceLocal decimal(7,3) NULL,
Cost int NULL,
MktValNet int NULL,
GLPeriod int NULL,
Beta decimal(4,2) NULL,
BetaExpNet int NULL,
BetaExpGross int NULL,
Delta decimal(4,2) NULL,
DeltaExpNet int NULL,
DeltaExpGross int NULL,
Issuer varchar(48) NOT NULL,
Country varchar(30) NOT NULL,
Region varchar(20) NOT NULL,
Sector varchar(30) NOT NULL,
Industry varchar(48) NOT NULL,
MktCapCategory varchar(24) NULL,
MktCapEnd int NULL,
Date date NOT NULL,
PortfolioID AS BbgID+LSPosition+ Convert(varchar(8),Date,112) Persisted Primary Key
)
GO
が第二のテーブルです毎日DailyPortfolioテーブルに-100行が追加されます(テーブルには現在約32,000行あります)。 DailyStatsテーブルに1営業日ごとに1行が追加されます(現在約500行あります)。 Daily PortfolioテーブルのDate列には、DailyStatsテーブルのDate列とのForeign Key関係があります。
最後の四半期を日付範囲として使用して、両方のテーブルのいくつかの列を含むビューを作成する必要がありました。このビューの最後の列は、四半期の3ヶ月のそれぞれの最初の日付にNAVを使用して平均が計算される、計算のNAV列の平均を使用します。ビューのDDLは次のとおりです。
CREATE VIEW Portfolio.PNLLastQTD
AS
WITH CTE1
AS
(
Select Date, NAV,YrMn, ROW_NUMBER() OVER (PARTITION BY YrMn ORDER BY Date) AS Row
FROM Portfolio.DailyStats
WHERE DATE BETWEEN
(SELECT Convert(date, DATEADD(q, DATEDIFF(q,0,GETDATE()) -1 ,0)))
AND
(SELECT Convert(date, DATEADD(s,-1,DATEADD(q, DATEDIFF(q,0,GETDATE()),0))))
),
CTE2
AS
(
SELECT AvG (NAV) As AvgNAV
FROM CTE1
WHERE Row=1
)
SELECT IssuerLS, Issuer, Ticker, SUM (GLPeriod) As [PNL],
CAST(SUM(GLPeriod)As Decimal (13,2))/CAST(CTE2.[AvgNAV] As Decimal (13,2)) as [%ofNAV]
FROM Portfolio.DailyPortfolioIssuerLS ls
JOIN cte2 on 1=1
WHERE ReportDate
BETWEEN
(SELECT Convert(date, DATEADD(q, DATEDIFF(q,0,GETDATE()) -1 ,0)))
AND
(SELECT Convert(date, DATEADD(s,-1,DATEADD(q, DATEDIFF(q,0,GETDATE()),0))))
GROUP BY
Issuer, Ticker, IssuerLS, CTE2.[AvgNAV]
GO
ビューは正常に動作しますが、実行には約20秒かかります。私はここにいくつかの質問があります:
- ビューのDDLにいくつかの変更が加えられますか?
- DailyPortfolioテーブルの(可能な場合)日付列に非クラスタ化インデックスを作成することをお勧めしますか?
- この特定の問題のクエリパフォーマンスを向上させるために何か考えておくべきことはありますか?
ありがとうございました。私がSQLに慣れてきたので、あからさまな間違いを許してください。
この記事はdba.stackexchange.comとcodereview.stackexchange.comに投稿していますが、役に立つ回答もあります。 – scsimon
クエリに含まれるテーブルに適切なインデックスを付けることで、パフォーマンスが向上する可能性があります。 SSMSで実行計画を分析すると、おそらくいくつか提案されます。 –