我有一张大桌子,并且正在使用SQL Server2017。该表包含下面显示的4列。
Column name Data type
IndexDate date
Code nvarchar(20)
Sedol nvarchar(7)
Wgt float
该表包含不同股票市场指数(例如,S&P 500,Russell 1000,FTSE 100等)的每日数据以及该指数中每只股票的权重。因此,通常每天将大约16,000行数据添加到数据库中。
数据从2000年之前开始。目前大约有6000万行。
最近人们想查询表并具有如下结构,
Sedol 06-03-2019 06-04-2019 06-05-2019 ...
ABC 0.03 0.0301 0.031
MNB 0.015 0.0147 0.0145
LPK 0.02 0.0201 0.0201
因此,我创建了一个使用数据透视功能的动态存储过程。如下图所示。它包含三个参数,两个用于日期范围的日期,另一个用于索引代码。
declare @dates nvarchar(max) = ''
select @dates = @dates + QUOTENAME(date) + ','
from DVLP_QES_MS.dbo.DateDimension where date >= @dateFrom and date <= @dateTo and IsWeekend = 0
set @dates = SUBSTRING(@dates, 1, len(@dates) - 1)
declare @q nvarchar(max) = ''
set @q = 'select * from
(
select Sedol, wgt, w.Date
from tblBMWeights w right join tblDates d on w.Date = d.Date
where Code = ''' + @bm + ''' and d.IsWeekend = 0 and d.Date >= ''' + convert(varchar(10), @dateFrom, 110) + ''' and d.Date <= ''' + convert(varchar(10), @dateTo, 110) + '''
)source pivot(max(wgt) for Date in (' + @dates + ' )) as pvt order by Sedol'
exec(@q)
通常这似乎可行,查询6个月的数据大约需要2秒钟。但是,现在需要进一步查询数据。
18个月大约需要14秒 30个月大约需要40秒 3年大约需要1分钟。
我在表上创建了索引,以帮助提高查询效率。我的问题是我的表应该如何结构,如何提高性能,以使3年的数据查询不需要1分钟?显然其他人有更大的表,他们如何处理超过1亿行的表?我应该有多个桌子吗?
我已经保存了执行计划,但似乎无法将其附在这篇文章上。
更新
这是my plan
的链接三个索引
1st)
NONCLUSTERED INDEX [IDX_tblBenchmarkWeights_CodeDate_Sedol] ON [dbo].
[tblBenchmarkWeights]
(
[Code] ASC,
[Date] ASC
)
INCLUDE ( [Sedol]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO
2nd)
NONCLUSTERED INDEX [IDX_tblBenchmarkWeights_CodeDateSedolWgt] ON [dbo].
[tblBenchmarkWeights]
(
[Code] ASC,
[Date] ASC
)
INCLUDE ( [Sedol],[Wgt]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO
3rd)
NONCLUSTERED INDEX [IDX_tblBenchmarkWeights_DateSedol] ON [dbo].
[tblBenchmarkWeights]
(
[Date] ASC
)
INCLUDE ( [Sedol]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO
我的日期表上的最后一个索引
NONCLUSTERED INDEX [IDX_DateDimension_IsWeekendDate] ON [dbo].[DateDimension]
(
[IsWeekend] ASC,
[Date] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO
答案 0 :(得分:-1)
要提高选择查询的性能,请遵循以下约束:
仅选择您需要的字段, 快速创建索引以快速查找表,而不是依赖表扫描, 使用EXISTS代替IN检查数据是否存在, 在查询任何表中的数据时,在“选择并连接”上使用WITH(NOLOCK)表提示,以避免死锁, 使用try catch块以避免死锁情况, 在列字段上使用适当的数据类型, 在SQL Objectname之前使用架构名称, 在查询中使用交易