Sql server SQL Server:如何提高WHERE子句中具有多个CTE和子查询的查询的性能
我有以下两个表格:Sql server SQL Server:如何提高WHERE子句中具有多个CTE和子查询的查询的性能,sql-server,sqlperformance,Sql Server,Sqlperformance,我有以下两个表格: 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
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
这是第二张表:
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-100行添加到DailyPortfolio表中(该表当前约有32000行)。每个工作日向DailyStats表中添加1行(当前约有500行)。Daily Portfolio表中的Date列与DailyStats表中的Date列具有外键关系
我必须创建一个视图,其中包含两个表中的一些列,并使用last quarter作为日期范围。该视图的最后一列在其计算中使用了NAV列的平均值,其中平均值是通过在季度中3个月的每个月的第一天使用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秒!我这里有几个问题:
谢谢你的帮助。请原谅明显的错误,因为我是SQL新手。我想结束这个问题的循环。这里我需要做的是创建两个非聚集索引。我使用了以下步骤:
USE [OurDB]
GO
CREATE NONCLUSTERED INDEX NCI_DailyPort_Issuer_Date
ON [Portfolio].[DailyPortfolio] ([Issuer],[Date])
GO
USE [OurDB]
GO
CREATE NONCLUSTERED INDEX NCI_DailyPort_Date_INC_DexpN_Issuer
ON [Portfolio].[DailyPortfolio] ([Date])
INCLUDE ([DeltaExpNet],[Issuer])
GO
注意:如果右键单击通知您缺少索引的行,您可以选择一个选项来查看索引的代码,这样可以节省您的时间。Id将此发布在dba.stackexchange.com和codereview.stackexchange.com上,尽管您也可以在此处找到有用的答案。您可能可以通过对查询中涉及的表使用适当的索引来提高性能。分析SSMS中的执行计划,可能会提出一些建议。